JavaScript에서 객체를 생성하는 방법은 크게 두 가지가 있습니다. (객체 리터럴 방식, 생성자 함수)
오늘은 객체 리터럴 방식과 생성자 함수의 차이와 생성자 함수에서의 this와 일반 함수에서 this의 차이에 대해서 알아보려고 합니다.
객체를 생성하는 방법은 아래와 같습니다.
객체 리터럴 방식
const obj = {
name: 'ReKoding',
age: 28
}
변수에 직접 {} 중괄호를 표시하여 {key: value}를 직접 입력하는 방식입니다. 흔히 많이 사용하는 방식입니다.
생성자 함수 방식
function Human(name, age) {
this.name = name;
this.age = age;
}
const obj = new Human('ReKoding', 28);
생성자 함수의 경우 함수명의 첫글자를 대문자로 표현합니다. 또한 기존 함수에 new 키워드를 사용하여 생성자 함수를 obj라는 인스턴스로 생성할 수 있습니다.
function Human(name, age){
this.name = name
this.age = age
}
const human = Human('SH', 28);
console.log(human.name); // 오류
현재 human 변수에 Human()함수를 호출한 값을 저장하고 있습니다. 이 때 Human() 함수의 반환 값은 undefeind입니다. 그러니 human의 값은 현재 undefined입니다. undefined.name을 참조하려고 하니 에러가 발생합니다.
또한 함수안에서 정의 된 this는 window 전역객체를 가르킵니다. 그렇기 때문에 this.name === window.name에 매개변수로 전달 받은 name 값을 저장하는 것입니다.
위 코드를 의도한대로 동작하려면 new 키워드를 사용하여 생성자 함수의 인스턴스로 만들어줘야합니다.
function Human(name, age){
this.name = name
this.age = age
}
const human = new Human('SH', 28);
console.log(human.name); // 'SH'
console.log(human.age); // 28
위 코드 처럼 new 키워드를 사용하여 함수를 반환 받으면 의도한바와 같이 생성자 함수를 만들어 함수 안에서 생성한 this는 빈 객체(여기서는 human)에 접근할 수 있습니다.
// 객체 리터럴 방식
const food = {
fruit: 'apple',
rice: 'ramen'
}
console.dir(food)
// 생성자 함수 방식
function Food(fruit, rice) {
this.fruit = fruit;
this.rice = rice;
}
const food1 = new Food('tomato', 'tteokbokki');
console.dir(food1);
const food2 = new Food('banana', 'chicken');
console.dir(food2);
위 코드와 같이 생성자 함수를 이용하여 객체를 생성한다면 동일한 코드를 쉽게 재사용할 수 있다는 장점이 있습니다.
객체 리터럴 방식은 생성자가 Object이고, 생성자 함수 방식은 생성자가 Food 입니다. 여기서 알 수 있는 점은 프로토타입이 다르기 때문에 상위 객체가 다르다는 것을 알 수 있습니다.