2012-06-16 5 views
4

프로토 타입 언어 개체는 기본적으로 서로 복제 할 수 있습니다. x = new Bla(); :자바에서 프로토 타이핑

Bla = function() 
{ 
    this.a = 1; 
} 

는이 같은 객체의 새로운 인스턴스를 만들 수 있습니다

그래서, 우리는 생성자 함수가 있다고 가정 할 수 있습니다. 지금은 Bla.prototype.b = 2를 작성한다면, x.a 반환 1.

x.b 2. 반환하지만, 왜? x가 "복제 된"Bla 인 경우 Bla.prototype을 참조하지 않고 Bla.b = 2이라고 말하면서 왜 동일한 기능을 사용할 수 있습니까? 이것은 this 키워드와 관련이 있습니까?

답변

10

인 ECMAScript를 보여 희망 완전한 샘플을 추가 (JavaScript)는 "프로토 타입 기반 상속"을 지원합니다. 즉, JS의 "클래스"와 "인스턴스"는 구별되지 않습니다. 다른 언어의 OOP와 대립하면, JS에서는 "클래스"와 "인스턴스"는 기본적으로 같습니다.

"Bla"를 정의하면 즉시 사용할 수 있지만 인스턴스로 사용할 수도 있습니다. "prototype"을 사용하여 동일한 속성 및 메서드를 사용하여 다른 인스턴스에 대해 객체 "Bla"의 초기 정의 (!)를 복제합니다. 다른 OOP 언어에서는 정의 부분에 "클래스"가 있습니다.

당신이 (읽기 : 클래스 "쏴") "쏴"의 프로토 타입을 확장 할 때 prototype 개체가 경우에 인 초기 정의 후 현재와 미래의 모든 인스턴스에 새 속성/함수를 추가 Bla.

// when defining "Bla", the initial definition is copied into the "prototype" 
var Bla = function() 
{ 
    this.a = 1; 
} 
// we can either modify the "prototype" of "Bla" 
Bla.prototype.b = 2; 
// or we can modify the instance of "Bla" 
Bla.c = 3; 

// now lets experiment with this.. 

var x = new Bla(); // read: "clone the prototype of 'Bla' into variable 'x'" 
alert(x.b);  // alerts "2" -- "b" was added to the prototype, available to all instances 

alert(x.c);  // undefined -- "c" only exists in the instance "Bla" 
alert(Bla.c); // alerts "3" -- "Bla" is an object, just like our new instance 'x' 

// also note this: 
Bla.a = 1337; 
var y = new Bla(); 
alert(y.a);  // alerts "1" -- because the initial definition was cloned, 
       // opposed to the current state of object "Bla" 
alert(Bla.a); // alerts "1337" 

마지막 예에서 보듯이, "프로토 타입"의 개념은 복제되지 않도록 할 필요가있다 : 당신이 지금 혼동하는 경우

, 난이 코드 예제는 차이를 발견하는 데 도움이 될 수 있습니다 생각 개체의 현재 "상태".

이 방법으로 구현되지 않으면 원본 객체 "Bla"가 복제되기 전에 사용/수정 된 경우 현재 상태가 복사되므로 이상한 결과가 발생할 수 있습니다 . 그래서 디자이너는 prototype 구조로갔습니다.

"Bla"는 정적 정의가 아닙니다. "클래스"는 다른 OOP 언어입니다.

프로토 타입에는 ECMAScript 구조, 상태 및 행동 상속을 구현하는 데 사용되는 객체입니다


ECMAScript specification

prototype 말한다. 생성자가 객체를 만들면 해당 객체는 속성 참조를 확인하기 위해 생성자의 관련 프로토 타입을 암시 적으로 참조합니다. 생성자의 연관된 프로토 타입은 프로그램 표현식 constructor.prototype에 의해 참조 될 수 있으며 객체의 프로토 타입에 추가 된 속성은 상속을 통해 프로토 타입을 공유하는 모든 객체에 의해 공유됩니다. 같은

모든 JS 프레임 워크 동등한 이름의 내장 객체 Javascript를의 기능을 확장하기 위해이 기능을 많이 사용합니다 "prototype"또는 jQuery. 내 느림에

Array.prototype.forEach = function each(iterator, context) { 
    for (var i = 0, length = this.length >>> 0; i < length; i++) { 
    if (i in this) iterator.call(context, this[i], i, this); 
    } 
} 
+1

죄송하지만 좋은 대답, 감사 :

는 예를 들어, JS 프레임 워크는 "prototype는"JS이없는 기능을 추가하는 방법 forEach와 네이티브 array 객체를 확장! – corazza

4

클래스와 인스턴스의 차이와 관련이 있습니다. x는 클래스 Bla의 인스턴스입니다. x.b = 2로 설정하면 해당 인스턴스의 특성 b를 추가/설정합니다. b의 프로토 타입에 b를 설정하면 해당 클래스 및 기존 인스턴스 각각에 대한 속성을 만듭니다. 동시에 인스턴스 생성자에서 a와 같이 생성자에서 설정하는 것의 차이점은 인스턴스에서 변경되면 잘 변경된 것입니다. b가 변경되면 프로토 타입 b는 이전 값과 함께 계속 존재하지만 새 값을 갖는 인스턴스에 대해 새 특성 b가 작성됩니다. 코드 샘플보다 훨씬 덜 분명하다 텍스트 때때로 실현

편집 (이 기본값으로 재설정 유용 할 수 있습니다) 그래서 차이를

​function bla(){ 
    this.a= 1; 
} 

var x = new bla(), 
    y= new bla(); 


bla.prototype.b= 2; 
x.c = 3; 

//x already exists, but b is still set 
//by setting the prototype all existing instances are changed 
console.log(x.b); //2 
console.log(y.b); //2 

//because c has been explicitly set, it only exists on instance x 
console.log(x.c); //3 
console.log(y.c); //undefined 


x.b = 6; //at this point 
//as mentioned, setting a property on an instance, only affects 
//that instance 
console.log(x.b); //6 
console.log(y.b); //2 

//but, because b is also a prototype property, it can be 'reset' 
//by deleting the instance property 
delete x.b; //removes the instance b 
delete y.b; //on y this does nothing, because only the prototype property exists 
console.log(x.b); //2 (reset to prototype) 
console.log(y.b); //2 

//the final difference, because a is a class bla property, and 
//not of its prototype, deleting property 'a', will actually cause a remove 
delete x.a; 
console.log(x.a); //undefined 
관련 문제