인스턴스란 정확히 무엇을 의미하는 용어일까? 꽤 열심히 구글링을 했지만, 어느 곳에서도 고개를 끄덕일만큼 명쾌한 설명을 해주지 않았다.(내가 느끼기에)
그래서 그냥 MDN이 instanceof 연산자에 대해 설명한 글에 기초해서 인스턴스가 무엇인지 이해하기로 했다.
a instanceof B 는 a가 B의 인스턴스라면 true를 반환하고, 아니라면 false를 반환한다.
MDN에서는 instanceof 연산자에 대해 이렇게 설명하고 있다.
instanceof 연산자는 object의 프로토타입 체인에 constructor.prototype이 존재하는지 판별합니다.
나는 프로토타입 체인에 대해 알고 있으니, instanceof 연산자가 무엇인지도 알 수 있는 자격이 있다.
코드를 살펴보자.
var Cat = function(name, age) {
this.name = name;
this.age = age;
}
var myCat = new Cat("커비", 1);
console.log(myCat instanceof Cat); //true
console.log(myCat instanceof Object); //true
console.log(myCar instanceof Function); //false
솔직히 말하자면 myCat instanceof Function이 true를 반환할 거라고 생각했다. myCat.__proto__.constructor.__proto__가 Function.prototype이니까.. 근데 아니었다!
나는 저번 포스트를 쓰며 prototype chain에 대해서 잘못 이해하고 있었다.
이번엔 제대로 이해한 게 맞다면, 어떤 객체의 [[Prototype]]이 쭉 이어져 있는 것을 prototype chain이라고 한다.
그래야 지금 이 코드가 이렇게 실행될 수 있는 거니까.
이것은 내가 저번 포스트에서 만들었던 myCat의 prototype 전개도이다.
이 전개도는 잘못 된 것이 아니다. 다만 prototype chain에 대한 설명도 추가하자면 이렇게 된다.
이거다! 이게 맞다! myCat은 prototype chain에 의해 Cat.prototype과 Object.prototype에 접근할 수 있다.
Cat.prototype.constructor는 Cat 생성자 함수이며, Object.prototype.constuctor는 Object 생성자 함수이다.
그래서 myCat은 Cat의 인스턴스이며 Object의 인스턴스인 것이다!
그리고 이게 왜 설명하기 힘든지도 알았다.
object가 자신의 prototype chain으로 접근할 수 있는 모든 prototype.constructor는 자신을 인스턴스로 가지고 있다.
나는 이 이상으로는 설명할 수가 없다...
인스턴스는 ~이다. 로 설명할 수 있는 게 아니다. ~의 인스턴스는 ~이다. 라고 밖에는 설명할 수 없다.
var Cat = function(name, age) {
this.name = name;
this.age = age;
}
var myCat = new Cat("커비", 1);
console.log(myCat instanceof Cat); //true
console.log(myCat instanceof Object); //true
console.log(Cat instanceof Function); //true
console.log(Cat instanceof Object); //true
위에 있는 prototype 전개도를 보며 코드를 읽으면 이해하기 더 쉽다.
- myCat.__proto__.constructor는 Cat이다. true
- myCat.__proto__.__proto__.constructor는 Object이다. true
- myCat.__proto__.__proto__.__proto__는 null이다. 그러므로 myCat은 Cat과 Object만이 인스턴스로 소유한다.
- Cat.__proto__.constructor는 Function이다. true
- Cat.__proto__.__proto__/constructor는 Object이다. true
- Cat.__proto__.__proto__.__proto__는 null이다. 그러므로 Cat은 Function과 Object만이 인스턴스로 소유한다.
그리고 알 수 있는 사실은 JS에 존재하는 모든 객체는 Function의 인스턴스이며 Object의 인스턴스이다.
왜냐하면 객체는 생성자 함수로 만들어졌고, 모든 생성자 함수는 Function의 인스턴스이며, Function은 Object의 인스턴스이기 때문이다.
prototype에 관한 포스트를 쓰기 이전에, 인스턴스에 관한 포스트를 먼저 쓰려고 했었다. 하지만 쓸 수 없었다. prototype chain이 뭔지 이해하지 못 했기 때문이다.
prototype chain이 뭔지 이해하고서야 인스턴스가 무엇인지 이해했다. 그리고 prototype chain이 뭔지 이해하지 않고서는 인스턴스가 무엇인지 이해할 길이 없을 것이다.
이제 지식을 배울 때 조급해하지 않고 선행지식부터, 기본부터 차근차근 이해해야 겠다고 크게 느꼈다.