2013-09-04 2 views
0

여러 수준의 메소드 및 속성을 가진 객체를 갖고 싶습니다. 최상위 수준에는 속성과 메서드가 있습니다. 이러한 속성 중 일부는 두 번째 수준 메서드 및 속성의 네임 스페이스 역할을합니다.속성의 자바 스크립트 프로토 타입

//first level methods 
base.doStuff(); 
base.doMore(); 

//second level methods 
base.level2.doStuff(); 

직진 첫 번째 수준입니다 수행 :

function Base(foo) { 
    this.foo = foo; 
} 

Base.prototype.doStuff = function() { 
    console.log(this.foo); 
} 

Base.prototype.doMore = function() { 
    console.log(this.foo); 
} 

base = new Base("bar"); 
base.doStuff(); 

는 두 번째 수준에 접근 가능, 어디 "이"키워드 점 다시 자료 생성자 함수 표현?

+2

"포인트를 다시 기본 생성자에"- 그것은 나에게 완전히 명확하지 않다 무엇 너 여기서 말하는거야. 아마'base.level2'가'base'를 가리 키기를 원합니까? 이 작업의 재귀를 알고 있습니까? –

+0

네,'base.level2.doStuff()'에서'this'가'base' 인스턴스를 가리키고 있음을 의미합니다 – Fergal

답변

0

음,

base.doStuff(); 

base의 맥락에서 doStuff를 호출한다. 그것은 this를 오버라이드 (override)에 대해

base.doStuff.call(base); 

할 수 있습니다 callapply 어떤 기능과 동일합니다 :

var base = new Base(); 

var someFun = function() { 
    console.log (this === base); // true 
}; 

someFun.call(base); 

또한 익명 예 :

var anObj = { 
    method0: function() { 
     console.log (this === anObj); // true 
    } 
}; 

anObj.method1 = function() { 
    console.log (this === anObj); // true 
}; 

anObj.method0(); 
anObj.method1(); 

는 그래서 "두 번째 수준은"this 포인트 level2으로 이동하고 "첫 번째 수준"개체로 이동하지 마십시오.

1

은 프로토 타입없이이 작업을 수행하기가 훨씬 쉽다 :

function Base() { 
    var base = this; 
    base.level2 = { 
     moreStuff: function() { 
      // use "base" instead of "this" here 
     } 
    }; 
} 

이것은 당신의 예에서와 같이, 원형 방법 중 하나와 결합, 또는 방법은 생성자에서 base에서 직접 정의 할 수 있습니다. 단점은 새 객체를 인스턴스화 할 때마다 메소드 함수를 작성하므로 표준 프로토 타입 메소드의 공유 프로토 타입 장점이 누락된다는 것입니다.

당신이 할 수있는 새로운 프로토 타입 기반의 객체를 만들 수 있습니다 귀하의 level2 :

function Level2() {} 
Level2.prototype.moreStuff = function() { 
    // do stuff 
} 

function Base() { 
    this.level2 = new Level2(); 
} 

하지만 당신은 명시 적으로 결합하지 않는 한 base.level2의 방법이 base에 바인딩되지 않습니다. 다양한 라이브러리 bind 지원을 (예를 들어, 밑줄의 _.bind), 또는 일반 JS에서 작업을 수행 할 수 있습니다

function Base() { 
    var base = this; 
    base.level2 = new Level2(); 
    base.level2.moreStuff = function() { 
     return Level2.prototype.moreStuff.apply(base, arguments); 
    } 
} 

당신은 여기에서 더 단순화 할 수 있지만, 당신은 항상 한 방향으로 결합 된 새로운 방법을해야 할거야 또는 JS는 명시 적 바인딩없이 base.level2.moreStuff()에서 base까지 this을 할당하지 않기 때문에 - 대부분의 경우 첫 번째 옵션이 가장 쉽고 깨끗합니다.

하지만 정말로, 네임 스페이스만으로도 가치가 있습니까? 기능적 가치가 없다면 단순히 메소드를 level2MoreStuff() 등으로 호출하는 것보다 훨씬 어렵습니다.

+0

예 메서드 이름의 일부로 접두사와 밑줄이있는 메서드를 "네임 스페이스"할 것입니다 . – Fergal

0

이 정말 나쁜 생각이지만, 여기 간다 :

function Base() { 
    this.name = 'Base'; 
    this.level2 = new Level2(this); 
} 

Base.prototype.whatsMyName = function(){ 
    alert(this.name); 
}; 

function Level2(base) { 
    this.name='Level2'; 
    for(var func in Level2.prototype) { 
     this[func] = Level2.prototype[func].bind(base); 
    } 
} 

Level2.prototype.whatsMyName = function(){ 
    alert(this.name); 
}; 

var b = new Base(); 

b.whatsMyName(); //Base 
b.level2.whatsMyName(); //Also Base 

현재 실행을 볼 수 있습니다 http://jsfiddle.net/zLFgd/1/

관련 문제