var instance = new Constructor();
__proto__
를 통해 이 메서드들에 접근 가능instance.__proto__
방식으로 직접 접근 불가 => 브라우저 호환성을 위해 지원하고는 있으나 권장되지 않음Object.getPrototypeOf(instance)
/Refelect.getPrototypeOf(instance)
를 통해서 접근var Person = function(name){
this.name = name;
}
Person.prototype.getName = function() {
return this._name;
}
var suzi = new Person('suzi');
suzi.__proto__.getName(); // undefined (error 나지 않음)
Person.prototype === suzi.__proto__ // true
suzi
가 아니라 suzi.__proto__
라는 객체__proto__
는 생략 가능한 프로퍼티이다.suzi.__proto__.getName
=> suzi(.__proto__).getName
=> suzi.getName
생성자 함수의 prototype에 어떤 메서드나 프로퍼티가 있다면 인스턴스에서도 마치 자신의 것처럼 해당 메서드나 프로퍼티에 접근할 수 있게 된다.
var Constructor = function (name) {
this.name = name;
}
Constructor.prototype.method1 = function(){};
Constructor.prototype.property1 = 'Constructor Prototype Property';
var instance = new Constructor('Instance');
console.dir(Constructor); // 1번
console.dir(instance); // 2번
2번이 Contructor
로 출력되는 이유는 인스턴스가 해당 생성자 함수의 이름을 표기해 해당 함수의 인스턴스임을 표기하기 때문이다.
var arr = [1, 2];
console.dir(arr);
console.dir(Array);
__proto__
은 Array.prototype을 참조__proto__
가 생략 가능하도록 설계var arr = [1,2];
Array.prototype.constructor === Array // true
arr.__proto__.constructor === Array // true
arr.constructor === Array //true
var arr2 = new arr.constructor(3, 4);
console.log(arr2); // [3, 4]
[Constructor]
[instance].__proto__.constructor
[instance].constructor
Object.getPrototypeOf([instance]).constructor
[Constructor].prototype.constructor
[Constructor].prototype
[instance].__proto__
[instance]
Object.getPrototypeOf([instance])
var Person = function(name) {
this.name = name;
};
Person.prototype.getName = function() {
return this.name;
};
var iu = new Person('지금');
iu.getName = function() {
return '바로 ' + this.name;
}
console.log(iu.getName()); // 바로 지금
iu.__proto__.getName
이 아닌 iu 객체에 있는 getName 메서드가 호출console.log(iu.__proto__.getName()); // undefined
iu.__prototype
)를 가리키는데 prototype 상에는 name 프로퍼티가 없기 때문, prototype에 name 프로퍼티가 있었으면 그 값을 출력 했을 것.일반적으로 메서드 오버라이드가 된 경우 자신으로부터 가장 가까운 메서드에만 접근되나 그 다음으로 가까운
__proto__
에 접근도 가능하다.
__proto__
에는 Object.prototype이 연결var arr = [1, 2];
arr(.__proto__).push(3);
arr(.__proto__)(.__proto__).hasOwnProperty(2); //true
__proto__
프로퍼티 내부에 다시 __proto__
프로퍼티가 연쇄적으로 이어진 것var arr = [1, 2];
Array.prototype.toString.call(arr); // 1, 2
Object.prototype.toString.call(arr); // [object Array]
arr.toString(); // 1, 2
arr.toString = function() {
return this.join('_');
};
arr.toString(); //1_2
Object.prototype
이 언제나 프로토타입 체인의 최상단에 존재한다. 참조형 데이터뿐만 아니라 기본형 데이터도 __proto__
에 반복 접근 가능함으로서 최종적으로 Object.prototype에 접근 할 수 있기 때문var Grade = function() {
var args = Array.prototype.slice.call(arguments);
for (var i = 0; i <args.length; i++) {
this[i] = args[i]
}
this.length = args.length;
};
var g = new Grade(100, 80);
Grade.prototype = [];
console.log(g);
g.pop();
console.log(g);
g.push(90);
console.log(g);
g.__proto__
, 즉 Grade.prototype이 배열의 인스턴스를 바라보게 하면 된다.