"자바스크립트는 객체기반의 스크립트 언어이다."
"파이썬은 객체지향 언어이다."
파이썬을 먼저 접하다보니, 자바스크립트에서 말하는 '객체'라는 용어가 헷갈렸다.
이 참에 확실히 정리하고 넘어가자!
결론부터 말하자면 파이썬의 객체와 자바스크립트의 객체는 같은 개념이다!
하지만 적용하는 방식이 조금 차이가 있을 뿐.
무엇이 같고, 무엇이 다른지 알아보자.
일반적으로 말하는 '객체'의 개념에 대해 알아보자.
object, 객체는 사전 그대로 '물건, 물체'를 뜻한다.
풀어서 말하면 객체는 일상 속에서 파악할 수 있는 모든 것이다.
예를 들어, 나도 객체가 되고, 주변에 노트북, 마우스, 키보드, 가방 등등 모든 것이 객체가 된다. 심지어 컴퓨터 안에서 쓰이는 스크롤 바, 버튼, 체크박스도 객체이다.
그리고 객체는 속성(Attribute)과 행동(Behavior)로 이루어져 있다.
속성(Attribute)과 행동(Behavior)
== 상태(State)와 행위(Behavior)
== 프로퍼티(Property)와 메소드(Method)
모두 다 같은 의미!
예를 들어, '고양이' 객체는 이름, 나이, 품종, 건강상태 등의 속성을 가질 수 있으며, 잠자기, 먹기, 울기, 놀기 등의 행동을 가질 수 있다.
코드 형식으로는 아래와 같이 표현해볼 수 있다.
// 속성
cat.name = "Mori"
cat.age = 5
cat.family = "Short hair"
cat.health = 100
// 행동
cat.sleep()
cat.eat()
cat.mew()
cat.play()
정리하면 객체는 우리 주변의 사물(Object)을 상태(State)과 행위(Behavior)로 나타내어 추상화하는 개념이다.
파이썬에서는 모든 것이 객체이다.
숫자, 문자열, 함수, 클래스 등 내부에 존재하는 모든 값이 객체이다.
예를 들어, 문자 'a'는 파이썬에서 다음과 같이 객체화 시킨다.
파이썬에서는 단순하게 'a'라는 문자를 표현하는것으로 끝내는게 아니라, 'a'라는 문자 자체를 객체로 만들고 다양한 속성과 행동을 넣어뒀다.
이러한 객체들이 가진 속성을 attribute, 객체가 가진 행동들은 method라고 부른다.
자바스크립트에서는 원시 타입(Primitive Type)을 제외한 모든 것이 객체이다.
원시 타입에는 boolean, null, undefined, number, string, symbol이 있다.
(하지만 원시 타입 또한 값이 정해진 객체로 취급되어, 객체로서의 특징도 함께 가지게 된다.)
반대로, 원시 타입이 아닌 참조 타입(Reference Type)은 객체이다.
(자바스크립트에는 원시 타입과 참조 타입 2가지 자료형이 있다.)
참조 타입에는 객체, 배열, 함수 등이 있다.
자바스크립트에서는 객체가 가진 속성을 property, 행동을 method라고 부른다.
파이썬에서는 클래스를 이용해 객체를 생성할 수 있다.
클래스
class Cat:
def __init__(self, name, age, species):
self.name = name
self.age = age
self.species = species
self.health = 100
def eat(self):
self.health = self.health +1
def run(self):
print(self.name + ", Run!"
mori = Cat("Mori", 5, "Short hair");
tori = Cat("Tori", 10, "Scottish");
print(mori.age); // 5
print(mori.run()); // Mori, Run!
print(tori.name); // Tori
자바스크립트에서는 객체 리터럴, 함수 생성자, 클래스 등을 이용해 객체를 생성할 수 있다.
객체를 생성하는 방식이 다양한 이유는 원래 자바스크립트에서는 클래스 개념이 없었기 때문이다.
클래스 기반 객체 지향 언어는 클래스를 사전에 정의하고 필요한 시점에 인스턴스를 생성하는 방식으로 객체를 생성한다. 하지만 자바스크립트는 프로토타입 기반 객체 지향 언어로서 클래스라는 개념이 없고 별도의 객체 생성 방법이 발달했다.
ECMAScript 6에서 새롭게 클래스가 도입되었다. 프로토타입 기반 프로그래밍은 클래스가 존재하지 않는 객체지향 프로그래밍 스타일이다. 클래스없이 프로토타입 체인과 클로저 등으로 객체 지향 언어의 상속, 캡슐화(정보 은닉) 등의 개념을 구현한다. 하지만 클래스 기반 언어에 익숙한 프로그래머들은 혼란을 일으킬 수 있으며 자바스크립트를 어렵게 느끼게하는 하나의 장벽처럼 인식되었다. ES6의 클래스는 기존 프로토타입 기반 객체지향 프로그래밍보다 클래스 기반 언어에 익숙한 프로그래머가 보다 빠르게 학습할 수 있는 단순하고 깨끗한 새로운 문법을 제시하고 있다. ES6의 클래스가 새로운 객체지향 모델을 제공하는 것이 아니며 클래스도 사실 함수이고 기존 프로토타입 기반 패턴의 문법적 설탕(Syntactic sugar)이다.
--> 자바스크립트가 어렵게 느껴졌던 이유..?!
let cat = {
name: "Mori",
age: 5,
species: "Short hair",
health: 100,
eat: function() {
this.health = this.health + 1;
},
run: function() {
console.log(this.name + ", Run!");
}
}
console.log(cat.name); // Mori
console.log(cat.health); // 100
cat.eat();
console.log(cat.health); // 101
cat.run(); // Mori, Run!
function Cat(name, age, species) {
this.name = name;
this.age = age;
this.species = species;
this.health = 100;
this.eat = function() {
this.health = this.health + 1;
};
this.run = function() {
console.log(this.name + ", Run!");
};
}
const mori = new Cat("Mori", 5, "Short hair");
const tori = new Cat("Tori", 10, "Scottish");
console.log(mori.age); // 5
console.log(mori.run()); // Mori, Run!
console.log(tori.name); // Tori
객체 내부에서 프로퍼티를 이용해 메서드를 정의하면 생성된 모든 인스턴스에 인스턴스 개수만큼의 메서드가 생성된다. 이럴경우 인스턴스가 많아질 경우 동일한 메서드를 여러개 생성하게 되어 메모리 소비가 심해지게 된다. 이는 프로토타입 객체에 메서드를 정의하는 방식으로 해결할 수 있다.
function Cat(name, age, species) {
this.name = name;
this.age = age;
this.species = species;
this.health = 100;
}
Cat.prototype.eat = function() {
this.health = this.health + 1;
};
Cat.prototype.run = function() {
console.log(this.name + ", Run!");
};
const mori = new Cat("Mori", 5, "Short hair");
const tori = new Cat("Tori", 10, "Scottish");
console.log(mori.age); // 5
console.log(mori.run()); // Mori, Run!
console.log(tori.name); // Tori
class Cat {
constructor(name, age, species) {
this.name = name;
this.age = age;
this.species = species;
this.health = 100;
}
eat() {
this.health = this.health + 1;
}
run() {
console.log(this.name + ", Run!");
}
}
const mori = new Cat("Mori", 5, "Short hair");
const tori = new Cat("Tori", 10, "Scottish");
console.log(mori.age); // 5
console.log(mori.run()); // Mori, Run!
console.log(tori.name); // Tori
{}
중괄호 안에 키(key): 값(value)
형태의 데이터가 들어있는 것을 파이썬에서는 딕셔너리, 자바스크립트에서는 객체라고 한다.
형태는 같은데 무슨 차이가 있을까?
자바스크립트에서는 키로 값에 접근할 때 []
대괄호(Bracket notation), .
점 (Dot notation) 두 가지 방식으로 접근할 수 있다.
또한, '식별자 네이밍 규칙'을 준수한다면 키에서 따옴표를 생략할 수 있다.
식별자 네이밍 규칙 : 문자/숫자/언더스코어(_)/달러기호($)로 구성되며, 숫자로 시작하지 않아야 한다.(예약어 제외)
const cat = { name: "mori", age: 5 };
console.log(cat.name);
console.log(cat["name"]);
let name = "name";
console.log(cat[name]); // 대괄호 안에는 변수를 사용할 수 있다.
Dot notation vs Bracket notation
Dot notation는 어떠한 객체의 Key값을 정확히 알고 있을때 사용할 수 있다.
Bracket notation은 key가 따옴표로 감싸져 있지 않으면 변수로 해석해서 참조한다.
위의 코드를 보면 실제로 괄호 안에 name이 담겨져 있는것 처럼 보이지만, name이란 변수를 사용함으로써 실제 코드는 cat["name"]이란 내용이 담겨져 있게 된다.
이러한 방식은 주로 함수의 파라미터로 객체의 프로퍼티를 참조하고 싶을때 사용하는 방법이다.
반면에 파이썬은 Bracket notation 방식으로만 값에 접근할 수 있다.
또한, 키를 적을 때 따옴표를 꼭 써줘야 한다.
cat = {"name": "mori", age: 5 } # key에 따옴표 필수!
print(cat["name"])
# print(cat.name) # 안 됨!
name = "name";
print(cat[name]) # 대괄호 안에는 변수를 사용할 수 있다.
참고사이트
https://ko.javascript.info/object
https://wikidocs.net/20457
https://tutorialpost.apptilus.com/code/posts/js/js30-object/
https://blog.hexabrain.net/104
https://webclub.tistory.com/390
https://curryyou.tistory.com/189
https://velog.io/@bsjp400/JavaScript-객체Object란