2012-04-26 2 views
5

나는 새로운 개체를 만들 때 나 프로토 타입 객체를 선택할 수 있도록하는 방법이 (복사 "자바 스크립트 : 좋은 부품"책) :자바 스크립트 프로토 타입 동작

이제
Object.create = function(o) { 
    var F = function() {}; 
    F.prototype=o; 
    return new F(); 
} 

말을, 내가 가진 객체 :

var car = { 
    model: "Nissan" 
}; 

그리고 나는 "만들기"방법을 사용하여,이 개체를 기반으로 새로운 객체를 생성 :

var car1 = Object.create(car); 

을 그런 다음 자동차에 속성을 추가 할 수 있으며 동적으로 car1 (동적 프로토 타이핑)에 추가됩니다. 그래서 예를 들면 다음과 같습니다

car.year=2011;  // Gets added to "car"... 
alert(car1.year); // ... Is also avaialable to car1 

Q1)이 문제는 "년"이 car1 사용할 수 있습니다 이유는 자동차의 프로토 타입에 추가되었다 있음을 나타냅니다. 이 올바른지? 그렇지 않다면 "연도"가 추가되고 왜 "자동차"와 "car1"모두에서 사용할 수 있습니까?

또한 위임 규칙에 따라 객체에서 메소드를 찾을 수없는 경우 프로토 타입을 검색 한 다음 Object.prototype에 도달 할 때까지 체인의 모든 프로토 타입을 검사합니다. 이제 다음과 같이 입력하면됩니다.

Object.prototype.originCountry = "Japan"; 
alert(car.originCountry); // Outputs Japan 
alert(car1.originCountry); // Outputs Japan 

지금까지 그렇게 좋았습니다. 그러나, 나는 할 경우 :

Object.carColor= "White"; 
alert(car.carColor); // Error! 

나는 "차"( 예를 들어 위의 car.year을 볼 수있는 속성을 추가 할 때 Q2)는 자동차의 프로토 타입에 추가됩니다 그러나, 나는에 속성을 추가 할 때. 객체는, 그것의 프로토 타입 객체에 추가 얻을 경우? 프로토 타입의 객체에 추가되지 않습니다, 왜 대표단의 규칙에 따라, "차"로 그것을 사용할 수 없습니다?

왜 이런 일이 무엇입니까?

+0

나는 그 행동이 그 속성이 프로토 타입에 만들어 졌기 때문에 그것이 객체 자체에서 생성하려고 시도했을 때 그는 정의되지 않은 것을 던지고 프로토 타입을 통해 속성을 만들 때마다 그 프로토 타입으로 생성 된 모든 요소를 ​​만든다고 생각합니다. 그것을 상속한다. –

+0

당신의 Q2가 잘못 시작되었습니다 : 당신은'car'의 프로토 타입에 아무것도 추가하지 않았고, 당신은'car1'의 프로토 타입에 추가했습니다 (이것은'car'가 될 것입니다). – searlea

답변

5

이 작업을 수행 :

Object.carColor = "White"; 

그러면 carColor 속성이 Object의 프로토 타입에 추가되지 않습니다. 현재는 Object의 재산입니다. 당신이 기대하는 것을 확인하려면, 당신이 할 것 것은 : 그 후 다음

Object.prototype.carColor = "White"; 

:

alert(({}).carColor); // Will alert "White" 

그래서 여기서 발생하는 것입니다. {}을 포함하여 생성 된 객체 (이는 빈 객체 일뿐입니다)는 Object의 새 인스턴스이므로 Object 프로토 타입에 설정된 모든 속성을 공유합니다.

어떻게 Object.create 기능이 작동하는지. 행별로 살펴 보겠습니다.

1. var F = function() {}; 

본질적으로 빈 개체 인 새 기능을 만들면됩니다. {}과 같은 함수가 아닌 이유는 함수가 new 호출과 결합되어 함수가 생성자 역할을 수행하는 해당 객체의 새 인스턴스를 만들 수 있기 때문입니다.

2. F.prototype=o; 

작성한 오브젝트에 새 공백 기능의 프로토 타입을 설정합니다. 자, 이것은 순전히 참조입니다. 깊은 사본이 아닙니다. 제 말은 오브젝트 o이 변경되면 오브젝트의 인스턴스도 변경된다는 것입니다 (실제로는 변경되지 않지만 변경된 것처럼 보입니다.) 나중에 자세히 설명합니다.

3. return new F(); 

이제는 전달한 객체로 프로토 타입이있는 해당 함수의 새 인스턴스를 만듭니다.

당신이 다음 작업을 수행 할 때 :

var car1 = Object.create(car); 

당신은 프로토 타입을 가지고 car1car이있는 개체를 가져옵니다. 그래서 당신은이 작업을 수행 할 때

car.year = 2011 

car1 변화처럼되지 않습니다. 프로토 타입이 변경을 의미하는 객체와 더 비슷합니다. 당신은 같은 것을 할 때 그래서 : 프로토 타입을 가지고,

car1.year 

검색이 year라는 속성 (첫 번째 프로토 타입, 다음 개체에서) 만들어 밝혀됩니다 따라서 car1.year2011를 반환합니다.

  1. 프로토 타입은 인스턴스 사이에 공유 :

    그래서 결론은 이것이다.

  2. Object의 속성을 변경하더라도 인스턴스가 변경되지 않습니다.
+0

이것은 제가 시도하고있는 것입니다 알다. 귀하의 게시물에, 당신은 말했다 : [인용] 당신은 자동차를 가지고 프로토 타입을 가지고 car1 개체를 얻을. 그래서 당신이 할 때 : car.year = 2011 그것은 car1 변경과 같지 않다. 프로토 타입이 변경을 의미하는 객체와 더 비슷합니다. [/ quote] "car"(car.prop = value)에 뭔가를 추가하면 왜 프로토 타입에 추가 될까요?하지만 Object에 동일하게 적용하면 그렇지 않습니다. @Bergi –

+0

근본적으로 일어나고있는 일은 'car1.prototype'이'car' 만 아니기 때문에'car1.prototype'이 2011 년'car1.prototype.year = 2011'을 말하는 것과 동일하다는 것입니다. –

+0

실례지만 내 지식 부족에 대해, 왜 car1.prototype === 자동차인가? "create"함수는 새 객체의 프로토 타입을 기존 객체에만 설정합니다 (이 경우 car1의 프로토 타입이 car1을 가리킴) –

1

첫 번째 예에서는 car1 b의 프로토 타입에 추가하고 있습니다. (car === F.prototypecar1 instanceof F). 그래서 Q1 : 그렇습니다.

Object은 모든 개체의 생성자 함수이며 F은 사용자의 car1입니다. Object.prototype에 무언가를 추가하면 모든 객체에서 사용할 수 있습니다. 그렇게하지 않아야하는 이유가 있습니다. 이러한 열거되지 않는 속성은 모든 for-in-loops를 엉망으로 만듭니다. Object 생성자 함수의 속성을 설정하면 상속하는 내용에 아무런 변화가 없습니다. 잊지 말아야 할 점은 ObjectF 함수와 같으며 프로토 타입 설정에 대한 매개 변수는 o이 아닙니다. new Object()Object.create(Object.prototype)과 같습니다.

0

이 함수는 프로토 타입 객체를 선택하지 못하게합니다. 객체 생성자는 nmew 객체 생성자를 만들고, 객체 인수는 프로토 타입으로 생성 한 다음 생성자를 기반으로 새 객체를 반환합니다.

새 개체는 개체 인수에서 메서드와 속성을 상속합니다. 이것은 다른 사람들로부터 상속받은 새로운 객체를 생성 할 수있게하는 것입니다.

이 작동하는 이유

Object.prototype.originCountry = "Japan"; 
alert(car.originCountry); // Outputs Japan 
alert(car1.originCountry); 

(길 객체에 의해 확장되어서는 안 자바 스크립트 객체와 핵심이다)이이 처음을 확장하기 때문에

Object.carColor= "White"; 

는하지 않습니다 Object의 프로토 타입 객체. 즉, Object 생성자를 사용하여 객체를 빌드하면 해당 메서드와 속성이 상속됩니다.

나중에 우리는 Object 생성자에서 생성 된 객체에 전달되지 않는 정적 함수를 호출합니다.

Javascript에서 프로토 타입 상속에 대해 더 자세히 읽는 것이 좋습니다. 여기 몇 개의 링크가 있습니다.

http://www.webreference.com/programming/javascript/prototypal_inheritance/index.html http://www.htmlgoodies.com/html5/tutorials/javascript-prototypical-inheritance-explained.html#fbid=xEJ2PwtH2Oh

http://unscriptable.com/2007/04/17/inheritance-explained/

관련 문제