2009-12-22 2 views
4

개체 자체에서 함수 및 멤버를 선언하는 대신 .prototype을 사용하는 기술적 인 이유는 무엇입니까? 코드 예제로 설명하는 것이 가장 쉽습니다.Javascript에서 .prototype을 사용하는 이유

는 사용의 장점은 무엇 같습니다

RobsObject = function(data){ 
    this.instanceID = data.instanceID; 
    this._formButton = document.getElementById('formSubmit_' + this.instanceID); 
    if(this._formButton) 
    { 
     //set a click listener that 
     //points to this._onSubmit, this._onSuccess, and this.onFailure 
    } 

    this._onSubmit = function(type, args) 
    { 
     //make an ajax call 
    } 

    this._onSuccess = function(type, args) 
    { 
     //display data on the page 
    } 

    this._onFailure = function(type, args) 
    { 
     //show an alert of some kind 
    } 
}; 

감사 :

RobsObject = function(data){ 
    this.instanceID = data.instanceID; 
    this._formButton = document.getElementById('formSubmit_' + this.instanceID); 
    if(this._formButton) 
    { 
     //set a click listener that 
     //points to this._onSubmit, this._onSuccess, and this.onFailure 
    } 
}; 

RobsObject.prototype = { 
    _onSubmit: function(type, args) 
    { 
     //make an ajax call 
    }, 

    _onSuccess: function(type, args) 
    { 
     //display data on the page 
    }, 

    _onFailure: function(type, args) 
    { 
     //show an alert of some kind 
    }, 
}; 

으로 같은 개체의 내부에 함수를 선언에 반대한다.

편집 : 많은 사람들이 두 번째 코드 스 니펫에있는 내 기능이 공개되기 위해 앞에 'this'가 있어야한다고 지적했습니다. 그래서 나는 그것을 추가했다. 내 실수.

+0

두 번째 코드 스 니펫에서'this._onSubmit = ...','this._onSuccess = ... '등을 사용하셨습니까? 그렇지 않은 경우, RobsObject 생성자로 인스턴스화 된 객체의 속성이 아닙니다. –

답변

14

생성자 함수의 prototype에 선언 된 모든 것은 해당 생성자 함수의 모든 인스턴스에서 공유됩니다. 생성자 함수에서 함수를 정의하면 각 인스턴스는 함수의 자체 복사본을 가져와 메모리를 낭비합니다 (나중에 두 인스턴스간에 속성을 비교하면 잠재적으로 문제가 발생할 수 있음).

또한 예제에서 생성자 함수에 선언 된 함수는 함수의 범위에 대해 private입니다. 인스턴스의 멤버 메서드로 호출 할 수 없습니다. 이를 위해 당신은 개체의 속성에 할당해야합니다 : Prototypical Inheritance in JavaScript :

MyObject = functon() { 
    // ... 

    this.myMethod = function() { 
    // ... 
    }; 
} 

더글러스 크록 포드는 확실히 체크 아웃 가치가 프로토 타입 상속의 좋은 쓰기까지 있습니다.

UPDATE : 간단한 프로토 타입 요약

당신이 생성자 함수를 사용하여 새 객체를 생성, 함수의 prototype 속성 값은 새 개체의 프로토 타입 객체로 지정됩니다. (예, 이름이 혼동!)이 많은 클래스 기반 언어의 수퍼 클래스를 지정하는 것과 같다 (그러나 아주! 크록 포드의 페이지를 읽어보세요!)

// MyObject constructor function: 
MyObject = function() { 
    this.a = 1; 
} 

// Define an object to use as a prototype. 
var thePrototype = { b: 2 }; 

// Assign thePrototype as the prototype object for new instances of MyObject. 
MyObject.prototype = thePrototype; 

// Create an instance of MyObject. 
var x = new MyObject(); 
// Everything in thePrototype is available to x. 
console.log(x.b); 

// x's prototype is a reference to thePrototype, so updating it affects x. 
thePrototype.c = 3; 
console.log(x.c); 

// Setting properties on x always sets them *on x*, even if the property is 
// defined on the prototype: 
x.b = 0; 
y = new MyObject(); 
console.log(x.b); 
console.log(y.b); 
+0

링크 및 정보를 제공해 주셔서 감사합니다. 당신의 대답을 이해한다면, .prototype 속성/함수가 다른 언어의 정적 함수와 비슷하게 작동한다고 말할 수 있을까요? –

+1

아니요, 클래스 기반 언어에서 수퍼 클래스처럼 작동합니다. 정적 인 프로퍼티 또는 함수를 원한다면, 단순히 생성자의 프로퍼티에 할당하면됩니다 :'MyObject = function() {/ * ... /} MyObject.StaticMethod = function() {/ ... * /};' – Annabelle

+0

오, 오케이, 그건 의미가 있습니다. –

3

대답은 메모리입니다. 개체를 개체 자체에 넣으면 해당 개체의 모든 인스턴스에 메모리에 모든 구성원이 포함됩니다. 반대로 프로토 타입을 사용하는 경우 프로토 타입은 한 번만 존재하며 모든 인스턴스는 자신의 것처럼 프로토 타입을 액세스합니다.

0

첫 번째 경우 new RobsObject()으로 생성 된 개체의 속성은 _onSubmit(), _onSuccess()입니다. 그것들은 소위 개체의 공공 기능이라고합니다.

두 번째 경우에서 이러한 함수는 new RobsObject()의 속성이 아닙니다. 그러나 '공개'기능 중 하나에서 볼 수 있습니다 (귀하의 경우에는 아무 것도 없습니다). 사실 그들은 사적 기능입니다. 당신이 당신의 두 번째 조각이 방법 ...

RobsObject = function(data){ 
    this.instanceID = data.instanceID; 
    this._formButton = document.getElementById('formSubmit_' + this.instanceID); 
    if(this._formButton) 
    { 
     //set a click listener that 
     //points to this._onSubmit, this._onSuccess, and this.onFailure 
    } 

    this._onSubmit = function(type, args) 
    { 
     //make an ajax call 
    } 

    this._onSuccess = function(type, args) 
    { 
     //display data on the page 
    } 

    this._onFailure = function(type, args) 
    { 
     //show an alert of some kind 
    } 
}; 

를 쓴 경우

그러나, 결과는 동일합니다.

두 가지 규칙의 중요한 차이점은 첫 번째 방법에서는 두 번째 방법과 같이 많은 공용 함수간에 공유 할 수있는 개인 함수를 정의 할 수 없다는 것입니다. 프로토 타입을 정의하는 데 사용 된 Object 리터럴은 함수 본문처럼 클로저를 형성하지 않습니다. 예를 들어

,

function MyConstructor() { 
    var myPrivate = function() { 
    } 

    this.myPublic1 = function() { 
     myPrivate(); 
    } 

    this.myPublic2 = function() { 
     myPrivate(); 
    } 

} 

myPrivate()은 공공 기능 표시 함수이다.

+1

첫 번째 예제의 결과는 프로토 타입 객체를 사용한 경우와 실제로 같지 않습니다. 생성자 내에서 선언 된 메서드는 객체의 각 인스턴스에 대해 추가 메모리와 처리 시간을 사용합니다. 그러나 첫 번째 예에서는 위쪽면이 있는데, 메서드는 두 번째 예제에서 선언 한대로 개인 메서드에 액세스 할 수 있습니다. 프로토 타입의 메소드는 그렇지 않습니다. – Annabelle

+0

흠. 내가 참조. 결과적으로, 객체 생성은 객체가 생성 될 때마다 실행되어야하기 때문에 생성자 함수가 큰 경우 추가 메모리 외에도 약간 느려질 것이라고 생각합니다. –

+0

예. 즉, 전형적인 개인/공공 의미론을 정말로 원한다면, 그렇게하는 것이 유일한 방법입니다. – Annabelle

관련 문제