생성자함수와 비슷한 새로운 패턴의 함수를 보게 되었는데, 처음에 무척 혼란스러웠었다.
복습을 하면서 다시 구글링을 하다가 좋은 블로그의 글을 발견해서 새로 알게된 사실을 바탕으로 메모하려고 한다.
Reference : https://webclub.tistory.com/309
객체를 생성할 때 리터럴 또는 내장 생성자함수를 이용해서 만들 수 있다.
const object = {};
const object_1 = new Object(); // {}
const object_2 = Object(); // {}
const array = [];
const array_1 = new Array(); // []
const array_2 = Array(); // []
하지만 내장 생성자함수보다는 그냥 객체리터럴로 생성하는 게 더 권장하는 방법이라고 한다.
단순히 표기법이 간결해서 그런가 했더니
생성자함수는 실행문 형태이기 떄문에 ()
안에 인자를 받을 수 있는 구조라서 인자를 전달할 경우 예상한 것과 다른 객체를 반환할 수 있다는 사실!
아래에서 인자를 집어 넣었을 때 무슨 일이 생기는 지 보자.
/* Object를 프로토타입으로 하는 빈객체가 만들어진다. */
const obj = {};
obj.__proto__ === Object.prototype // true
obj.constructor === Object // true
/* 인자로 숫자를 전달했더니 Number객체로 만들어졌다! 🤭 */
const obj1 = new Object(1);
// === const obj1 = new Number();
obj1.__proto__ === Object.prototype // false
obj1.constructor === Object
obj1.constructor === Number
/* 인자로 문자열을 전달했더니 String객체로 만들어졌다! 🤭 */
const obj1 = new Object('안녕');
// === const obj1 = new String();
obj1.__proto__ === Object.prototype // false
obj1.constructor === String
obj1.constructor === String
자바스크립트에서는 new 키워드를 붙인 생성자함수로 생성자함수의 자식, 인스턴스를 생성할 수 있다.
사실 자바스크립트에서는 Class가 존재하지 않기 때문에, 객체를 생성하는 Class의 기능을
비슷하게 구현하는 하나의 방식일 뿐이다.
즉 new가 없이는 그저 보통의 함수에 불과하다.
하지만 new를 사용해서 객체를 생성하면 빈객체가 생성되고, 생성자함수 내부의 this 변수를 이용해서 부여한 프로퍼티와 메서드를 자식 인스턴스가 상속(엄밀히 따지면 상속은 아니지만)받아서 사용할 수 있다.
생성자함수 내부에서는 this는 빈객체다라고 선언하는 부분과 그 this를 리턴하는 부분이 투명인간처럼 안보인다고 생각하면 된다.
알고 있었던 내용이지만 코딩할 때는 주어진 시간 내에 풀어내야 한다는 압박감에 순간순간 잊어버리고 이게 뭐지 저건 뭐지 하게 되는 것 같다.
그래서 내부에서 this를 사용했다면 인스턴스를 만들때
new 붙이는 걸 까먹으면 안된다.
오류가 생길 수 있음!
const Dog = function (name) {
// const this = {}; 이게이게 생략되어 있는 것.
this.name = name;
this.say = 'walwal! I am badugi';
// return this; 이것도 생략된것.
};
const badugi = new Dog('badugi');
// Dog {name: "badugi", say: "walwal! I am badugi"}
그리고 위 코드는 아래처럼 표현할 수도 있다!!
=> this 객체는 생성자 함수를 프로토타입으로 가진다
const this = Object.create(Dog.prototype);
👍그리고 이 글을 쓰게된 중요한 포인트가 이제 등장한다.
바로 new 키워드 없이도 생성자함수와 자식객체를 비슷하게 구현할 수 있다는 사실.
const Cat = function () {
const cat = {}; // this = {} 대신 캣 = {}
cat.say = '냐옹';
cat.eat = 'yummy';
return cat; // return this 대신 return 캣
}
const miyaong = Cat();
// {say: "냐옹", eat: "yummy"}
암묵적으로 this를 리턴하는 생성자함수와 달리
일반 함수에서는 내부에서 선언한 빈객체를 꼭 리턴해줘야 한다.
그리고 이때는 new키워드를 안 붙여도 된다!!
빈객체를 만들지 않고 다음과 같이 아예 객체를 리턴하는 형태로 작성해도 된다.
const Cat = function () {
return {
say: '이렇게도 할수있다옹'
};
};
const nabi = Cat();
// {say: "이렇게도 할수있다옹"}
👍조금 복잡해보이지만 아래처럼 만들수도 있다.
colkiPrototype객체를 선언하고,
일반함수 MyCilki 내에서 Object.create()을 이용해서
프로토타입을 상속받는 colki객체를 만들고 리턴한다.
그렇게 되면 이 MyColki함수로 만들어지는 인스턴스들 역시
colkiPrototype의 프로퍼티와 메서드를 사용할 수 있게 된다:)
const colkiPrototype = {};
colkiPrototype.say = function () {
console.log('Do you love me?');
};
const MyColki = function () {
const colki = Object.create(colkiPrototype);
colki.name = 'hany';
return colki;
};
const mycolki = MyColki();
myColki.say(); // Do you love me?