2012-04-26 5 views
10
var someObj = function() { } 
var p = new someObj(); 

alert(someObj.prototype); // This works 
alert(p.prototype);   // UNDEFINED, but why? 

someObj.prototype.model= "Nissan"; 
alert(p.model);    // This works! I understand the dynamic nature of prototypes, but doesn't that mean that p.prototype === someObj.prototype? 

왜 이렇게 되나요? "p"는 "someObj"의 인스턴스이므로 프로토 타입이 정의되지 않은 이유는 무엇입니까? 내 말은, "someObj"프로토 타입에 속성을 추가하면 "p"에 액세스 할 수 있으므로 프로토 타입에 액세스 할 수없는 이유는 무엇입니까?Object.create()를 통한 Javascript 프로토 타입

답변

11

여기서 중요한 점은 기능 객체 prototype 속성이 객체의 프로토 타입이 아니라는 것입니다. new someObj을 통해 생성 한 객체의 프로토 타입으로 할당 될 객체입니다. ES5 이전에는 객체의 프로토 타입에 직접 액세스 할 수 없었습니다. ES5 기준으로 Object.getPrototypeOf을 통해하실 수 있습니다.

다시

alert(p.prototype); // UNDEFINED, but why?

이유는 p 객체가 "프로토 타입"이라는 속성을 가지고 있지 않은 것입니다. 기본 프로토 타입이 있지만 액세스하는 방식이 아닙니다.

모든 함수 객체에는 prototype이라는 속성이 있으므로 생성자 함수로 사용되는 경우 해당 생성자가 만든 객체의 기본 프로토 타입 속성을 정의 할 수 있습니다. 이 도움이 될 수 있습니다 : 마지막 줄은 다음과 같이 작동

function Foo() { 
} 
Foo.prototype.answer = 42; 

console.log(Foo.prototype.answer); // "42" 
var f = new Foo(); 
console.log(f.answer); // "42" 

그건 :

  1. f 객체를 가져옵니다.
  2. f자신의 속성은 "대답"이라고합니까?
  3. 아니요, f에 프로토 타입이 있습니까?
  4. 예, 프로토 타입의 자신의 속성이 "대답"이라고되어 ​​있습니까?
  5. 예, 해당 속성의 값을 반환하십시오.

질문 제목에 Object.create을 언급했습니다. Object.create은 생성자 함수와 완전히 별개임을 이해하는 것이 중요합니다. 그것은 언어에 추가되었으므로 생성자 함수를 사용하지 않기를 원했지만 객체를 만들 때 객체의 프로토 타입을 직접 설정할 수 있습니다.   —.

+0

우수 설명 –

+0

@TahaAhmad : 도와 줘서 기뻐요! –

2

이 경우 p = someObj.prototype이므로 p.prototype이 작동하지 않습니다.

기본적으로 new 연산자를 사용하면 someObj 생성자가 새 객체를 초기화하는 데 사용됩니다. 즉, 생성자의 프로토 타입의 속성과 메서드를 가진 개체를 반환합니다.

따라서 p = someObj.prototype이고 p는 생성자가 아니므로 p.prototype은 정의되지 않습니다.이 문서가 도움이 될 수

는이

http://www.htmlgoodies.com/html5/tutorials/javascript-prototypical-inheritance-explained.html#fbid=A2ikc3JLxeD

+0

Crowder의 답변에 따라 프로토 타입이 있으며 Object.getPrototypeOf (p)를 사용하여 액세스 할 수 있습니다. 필자의 이해가 정확하다면, 프로퍼티와 메소드가 객체의 새로운 인스턴스에 복사되지만, 이것이 p === someObj.prototype을 의미하지는 않습니다. 그것은 p.prototype === someObj.prototype을 의미합니다. –

1

p예를 someObj 더 설명합니다. 프로토 타입은 생성자에 속합니다. p.constructor.prototype

6

은 그 자체의 속성이 아니기 때문에 생성자 함수의 속성이기 때문에 p의 생성자 프로토 타입을 검색 할 수 있습니다. 그러나, prototype 객체는 생성자에 대한 참조를 가지고, 그래서 당신은 객체의 prototypeconstructor 속성을 통해 액세스 할 수 있습니다 : 당신은 생성자 함수의 초기 prototype 속성을 덮어 쓸 경우

function Foo() {} 

Foo.prototype.foo = "bar"; 

var c = new Foo; 

console.log(c.constructor === Foo); // true 
console.log(c.constructor.prototype); // { foo: 'bar' } 

그러나이 작동하지 않습니다 :

function Foo() {} 

// I overwrite the prototype property, so I lose the initial reference 
// to the constructor. 
Foo.prototype = { 
    foo: "bar" 
}; 

var c = new Foo; 

console.log(c.constructor === Foo); // false 
console.log(c.constructor === Object); // true 
console.log(c.constructor.prototype); // {} 

그런 이유로 ES5에서 도입 된 새로운 Object.getPrototypeOf 방법을 사용하는 것이 좋습니다.

function Foo() {} 

Foo.prototype = { 
    foo: "bar" 
}; 

var c = new Foo; 

console.log(c.constructor === Foo); // false 
console.log(c.constructor === Object); // true 
console.log(c.constructor.prototype); // {} 
console.log(Object.getPrototypeOf(c)); // { foo: 'bar' } 

또 다른 해결책은 당신이 프로토 타입에 constructor 참조를 복원 확인했을 것이다 :

function Foo() {} 

// Overwriting the initial prototype  
Foo.prototype = { 
    constructor: Foo, // restore the constructor reference 
    foo: "bar" 
}; 
+0

매우 유용한 블로그 포스트를 찾았습니다.이 대답과 결합하면 전체 프로토 타입의 광기에 대해 많은 혼란을 없앨 수 있습니다. http://blog.sklambert.com/javascript-prototype/ 다이어그램은이 해답을 이해하는 데 많은 도움이됩니다. 희망이 사람을 도움이됩니다. – Bruce

0

자바 스크립트에서 생성자은, 실제로 모든 기능은 프로토 타입 속성을 얻을. 객체 (즉, 키 - 값 쌍의 집합)에는 프로토 타입 속성이 없습니다. 위의 예에서

var someObj = function() { } // this is a function, so it has a prototype property 
var p = new someObj(); // this is an instance object, so it doesn't 

someObj.prototype은 정의되었지만 p.prototype은 정의되지 않습니다.