2010-07-30 4 views
1

수정 : 나는 모든 것을 생각하기 전에 게시했습니다. 여기 내 마음에 무엇을 더 잘 구현 한 것입니다 : Javascript inheritance idea (part 2)자바 스크립트 상속 아이디어?

그래, 그래서 난 당신이 각 인스턴스에 대한 방법을 복제하고 있기 때문에 다음이

function A() { 
    this.variable = 7; 
    this.method = function() { alert(this.variable); }; 
} 

alpha = new A(); 
beta = new A(); 

나쁜 것을 보았다. 그러나 다음을 수행 할 수없는 이유는 무엇입니까?

var A = new function() { 
    this.variable = null; 
    this.method = function() { alert(this.variable); }; 
}; 

var alpha = {variable: 8}; 
alpha.__proto__ = A; 

var beta = {variable: 9}; 
beta.__proto__ = A; 

그런 다음 메모리를 낭비하지 않고 메서드를 상속하고 새 인스턴스 변수를 지정할 수 있습니다.

물론이 패턴을 본 적이 없으므로 사용되지 않는 이유는 무엇입니까?

+0

엄청난 수의 물체를 가지고 있다면 원래의 기법이 나쁘다. 가장 예외적 인 경우를 제외하고는 성능/메모리 문제를 전혀 느끼지 못할 것입니다. – morgancodes

답변

2

순수 prototypical inheritance을 찾고 있다고 생각합니다.

ECMAScript 5th Edition 표준은 Object.create 메서드를 도입했으며이 메서드는 전달 된 첫 번째 인수 (null 또는 개체 일 수 있음)에서 직접 상속되는 개체를 만듭니다. 예를 들어

:

var A = { 
    variable: null, 
    method : function() { alert(this.variable); }; 
}; 

var alpha = Object.create(A); 
alpha.variable = 8; // or above `Object.create(A, {'variable': { value: 8 } });` 

var beta = Object.create(A); 
beta.variable = 9; 

이 방법은 그러나 대략 ECMA 스크립트 3 구현에 에뮬레이트 할 수 있으며, most recent browsers로 볼 수 있습니다 :

if (!Object.create) { 
    Object.create = function (o) { 
    if (arguments.length > 1) { throw Error('Second argument not supported'); } 
    if (o === null) { throw Error('Cannot set a null [[Prototype]]'); } 
    if (typeof o != 'object') { throw TypeError('Argument must be an object'); } 
    function F(){} 
    F.prototype = o; 
    return new F; 
    }; 
} 

에뮬레이트 할 수없는 몇 가지 기능이있다하는 것으로 ES3에서 두 번째 인수와 마찬가지로 새 Object.defineProperties 메서드에서 사용되는 설명자와 같은 속성 설명자가 필요합니다.

또한, Object.create 당신이 사용되지 않도록 패턴이 __ 프로토 __ 표준되지 않는 것입니다 그 [[Prototype]]

2

사용되지 않는 명백한 이유는 생성자가 생성자를 생성하는 대신 객체를 직접 생성한다는 것입니다. 나중에 다르게 작동하도록 생성자를 변경하면 코드가 손상 될 수 있습니다.

더 나은 솔루션은 전화를 알아내는 경우 자바 스크립트가 이미 객체의 메소드, 그 객체의 프로토 타입의 방법에서 보이는

function A(value) { 
    this.variable = value; 
} 

A.prototype.method = function() { alert(this.variable); }; 

될 것이다. 따라서 A의 프로토 타입에서 메서드를 정의하면 A가 만들거나 이미 만들었던 모든 A에 대해 정의됩니다.

+0

저는 A를 생성자 함수로 보지 않았습니다. 객체 인스턴스 그 자체이며, 알파와 베타를 프로토 타입으로 사용합니다.A의 메소드는 변경 될 수 있지만 변경 사항은 알파와 베타로 전파되므로 의도 한 결과입니다 (클래스의 객체보다 상속을 객체하는 것이 더 많은 객체입니다). 나는 var A = {variable : null, method : ...};를 할 수있었습니다. 그러나 A (var local = 3;)에 국한된 모든 변수도 상속 될 것이므로 의도하지는 않습니다. Clackford의 Object.create 메소드 (클래식 상속은 아니지만)와 비슷하지만 개인 변수가있는 것 같아요 ... – Nick

+0

글쎄, 그건 당신이 당신의 패턴을 많이 보지 못하는 또 다른 이유입니다. :) 고전적인 상속은 훨씬 더 보편적이며, 대부분의 프로그래머에게 익숙합니다. 실제로, 그게 내가 내 대답을 쓸 때 내가 생각하고 있었던 것이다. – cHao

0

null의 주요 이유를 설정하여 다른 개체에서 상속하지 않는 개체를 만들 수 있습니다 . firefox/chrome과 호환됩니다. 그러나 IE에서는 작동하지 않습니다.

또한 제안 된 코드에는 생성자가 없습니다. 올바른 구조로 객체를 초기화한다고 가정합니다.