2014-10-14 1 views
3

주된 이유를 않습니다 데프 만 만 "this.xxx"을 통해 "공공 분야"에 접근 기능 작동하고 Inheriting_FuncDef이 SuperFuncDef의 연장에 대한 지식이 있어야합니다, 다른 현명 "공공 필드는"충돌 일어날 것 :자바 스크립트는이 시간 함수 정의 내에서 상속 정의를 유지하기 위해 노력하고있다 "<strong>프로토를</strong>"를 사용

var G=function(){ 
    var g1state=0; 
    this.g1=function(){ 
     return g1state++; 
    } 
}; 
var E = function(){ 

    var e2state=0; 
    this.e2=function(){ 
     return e2state++; 
    } 
}; 
E.prototype=new G(); 

var F= function(){ 

    var f3state=0; 
    this.f3=function(){ 
     return f3state++; 
    } 
}; 
F.prototype=new E(); 


var xx = new F(); 
var xx2= new F(); 

console.log("xxg1:___"+xx.g1());//0 
console.log("xxg1:___"+xx.g1());//1 
console.log("xx2g1:___"+xx2.g1());//2 , need it to be 0, don't wanna share same super() instance/and closure. 


console.log("xxe2:___"+xx.e2());//0 
console.log("xxe2:___"+xx.e2());//1 
console.log("xx2e2:___"+xx2.e2());//2 , need it to be 0;don't wanna share same super() instance/and closure. 


console.log("xxf3:___"+xx.f3());//0 
console.log("xxf3:___"+xx.f3());//1 
console.log("xx2f3:___"+xx2.f3());//0 this f3() is not inherited from super(), and have the expected result. 

console.log(xx); 
console.log("xx instanceof E:___"+(xx instanceof E));//ture 
console.log("xx instanceof F:___"+(xx instanceof F));//true 
console.log("xx instanceof G:___"+(xx instanceof G));//ture 

"향상된 버전"의 경우 유일한 단점이있는 것 같습니다. "instancof"테스트는 정확할 수 없으며, 그렇지 않으면 사용할 수 있습니다. 그러나 "instancof"부정확성은 주요 단점입니다.

//i test it in ie 11, the result is the same. 
var G=function(){ 
    var g1state=0; 
    this.g1=function(){ 
     return g1state++; 
    } 
}; 
var E = function(){ 
    Object.setPrototypeOf(this,new G()); 
    var e2state=0; 
    this.e2=function(){ 
     return e2state++; 
    } 
}; 
//E.prototype=new G(); 
var F= function(){ 
    Object.setPrototypeOf(this,new E()); 
    var f3state=0; 
    this.f3=function(){ 
     return f3state++; 
    } 
}; 
//F.prototype=new E(); 

var xx = new F(); 
var xx2= new F(); 

console.log("xxg1:___"+xx.g1());//xxg1:___0 ,expected. 
console.log("xxg1:___"+xx.g1());//xxg1:___1 ,expected. 
console.log("xx2g1:___"+xx2.g1());//xx2g1:___0 ,expected. 


console.log("xxe2:___"+xx.e2());//xxe2:___0 ,expected. 
console.log("xxe2:___"+xx.e2());//xxe2:___1 ,expected. 
console.log("xx2e2:___"+xx2.e2());//xx2e2:___0 ,expected. 


console.log("xxf3:___"+xx.f3());//xxf3:___0 ,expected. 
console.log("xxf3:___"+xx.f3());//xxf3:___1 ,expected. 
console.log("xx2f3:___"+xx2.f3());//xx2f3:___0 ,expected. 


console.log(xx); 
console.log("xx instanceof E:___"+(xx instanceof E));//xx instanceof E:___false , expect to be true 
console.log("xx instanceof F:___"+(xx instanceof F));//xx instanceof F:___false, expect to be true 
console.log("xx instanceof G:___"+(xx instanceof G));//xx instanceof G:___true 

그래서 어느 방법으로도 완벽한 결과를 얻을 수 없습니다. 그리고 나는 "Funcref.prototype = new superFuncref()"상속 설정은 기본적으로 나를 위해 작동하지 않는다고 생각합니다.

내가 유일한 이유는 Object.setPrototypeOf (this, new SuperFuncRef())입니다. 왜냐하면 나는 모든 "instancof"절을 사실로 만들고 싶기 때문이다. 그렇지 않으면 SuperFuncRef()를 할 것이다. apply (this), 모든 함수를 "this"로 먼저 복사 한 다음 로컬 override를한다. 그러므로 새로운 F()는 단지 F의 인스턴스입니다. 그것은 내가 원한 것이 아닙니다.

감사합니다. 상관 없거나 가치가 없다고 생각한다면 혼자 남겨주세요. down_vote에 더 많은 시간을 낭비하지 마세요. 나는 그 경계에 있습니다. 아니면 아래에 설명하여 영어 문법을 가르쳐 줄 수 있습니다. 당신이 대답을 하든지하지 않더라도, 내가 다시 만족할 때까지 다시 포맷 할 것입니다.

+0

'때문에, 왜 말합니까" "버전을 개선? 'Object.setPrototypeOF()'및'Object.getPrototypeOf'를 사용해야합니다. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Object/proto – laruiss

+0

생각해보십시오 - 생성자 함수 (객체를 만들 때마다) 많은 시간을 호출 할 수 있지만 prototype 속성을 설정하는 작업은 한 번만 수행되므로 객체가 만들어 질 때마다 수행하면 안됩니다. 또한 프로토 타입 속성은 생성자 함수가 호출되기 전에 이미 설정되어 있어야합니다. 그래서 생성자 내부에 설정하면 어떻게됩니까? ... – YK1

+0

哦 ... 매우 합리적입니다. writing_convenience에 관해서는, 왜 그 글에 답하지 않으시겠습니까? 나는 그것을 대답으로 받아 들일 것이다. – Johnny

답변

0

특히이 하나에 대답하지 않지만 대답은 종류의,이 링크에서 제공되는이 메커니즘은 동일합니다 :

https://stackoverflow.com/a/26300006/289701

내가 전에 알고하지 않는 하드, 슬픈 진실 즉 : 생성자의 모든 인스턴스는 동일한 생성자를 가지므로 동일한 constructor.prototype과 유일한 인스턴스가 있습니다._proto__ "는 FuncDef의 모든 인스턴스에 대해 위조 할 수 없습니다

function ClassNameHere(){} 
var x = new ClassNameHere(); 
var x2 = new ClassNameHere(); 
console.log(x.__proto__===ClassNameHere.prototype)// true. 
console.log(x.__proto__===x2.__proto__)// true. 

을 그래서 방법의 사용이없는 경우에만"자바 스크립트 상속 "java_Class 모두 기능 구축 : (private_fields, 상속)

하드, 슬픈 사실은 "javascrpit 상속"을 한 번만 설정하면된다.

이 솔루션은 SuperFuncRef.call (this)을 사용하여 SuperFunc의 모든 메소드를 복사하고 새로운 범위를 복사 한 다음 impl override를 수행하십시오. "superFunc의 light_weight 인스턴스"를 사용하여 "상속"/ "상속 _relationship/체인 "

나는 그것이 나쁜 코드인지 모르겠지만, 결과는 내가 원하는 무엇인가 : __proto__`가되지 않습니다

var E= function(c){if(c) return this; 

    var ex= 0; 
    this.x=function(){ 
     return ex++; 
    }; 
} 

var F= function(c){ 

    if(!(this instanceof E)){ 
     this.__proto__.__proto__=new E(true); 
    } 
    if(c) return this; 
    E.call(this); 

    var fx=0; 
    this.y=function(){ 
     return fx++; 
    }; 
} 

var G= function(c){ 

    if(!(this instanceof F)){ 
     this.__proto__.__proto__=new F(true); 
    } 
    if(c) return this; 
    F.call(this); 

    var lsuper={}; 


    var gx=0; 

    this.z=function(){ 
     return gx++; 
    }; 

    if(this.y)lsuper.y=this.y; 
    this.y=function(){ 
     return lsuper.y()+"hehe"; 
    } 
} 

var x=new G(); 
console.log("-------------") 
var x2= new G(); 
console.log("-------------") 
var x3= new G(); 
console.log("x.x():___"+x.x());//0 
console.log("x.x():___"+x.x());//1 
console.log("x.x():___"+x.x());//2 
console.log("x2.x():___"+x2.x());//0, expected, different scope 
console.log("x2.y():___"+x2.y());//0hehe 

console.log(x); 

console.log("x instanceof G:___"+(x instanceof G));//true 
console.log("x instanceof F:___"+(x instanceof F));//true 
console.log("x instanceof E:___"+(x instanceof E));//true 

console.log("x2 instanceof G:___"+(x2 instanceof G));//true 
console.log("x2 instanceof F:___"+(x2 instanceof F));//true 
console.log("x2 instanceof E:___"+(x2 instanceof E));//true 

console.log("x3 instanceof G:___"+(x3 instanceof G));//true 
console.log("x3 instanceof F:___"+(x3 instanceof F));//true 
console.log("x3 instanceof E:___"+(x3 instanceof E));//true 
0

프로토 타입 할당 남용으로 독립된 격리 상속? 끝낼 수 있습니다.

function Class1() { 
    if (!Class1.done) { 
     Class1.prototype.meth = function(){} 
     Class1.done = true 
    } 
    this.ownBaseField = 1 
} 

function Class2() { 
    Class1.call(this) 
    if (!Class2.done) { 
     Class2.prototype.__proto__ = Class1.prototype 
     Class2.done = true 
    } 
} 

function Class3() { 
    Class2.call(this) 
    if (!Class3.done) { 
     Class3.prototype.__proto__ = Class2.prototype 
     Class3.done = true 
    } 
} 

var o = new Class3() 
;[o instanceof Class3, o instanceof Class2, o instanceof Class1, 'meth' in o] 
// true,true,true,true 

이 예제는 연습용으로 만 사용하십시오. 프로토 타입 할당과 마찬가지로이 방법은 사용하지 않는 것이 좋습니다.

+1

이 코드에는 큰 빨간색 "never do this"경고가 있어야합니다. 또한 세미콜론을 사용해야합니다. (아니면 "나쁜 코드"요인을 높이려는 시도에서 그들을 내버려 두었습니까?) – JLRishe

2

왜 생성자 내부에서 모든 작업을하려고합니까? 비효율적이며 목적이 없습니다. 드문 경우가 아니면, __proto__을 만지지 않아야합니다.

다음은 상속을 설정하는 (그리고 실행 중 모든 멤버 함수의 별도 복사본이없는) 정통적인 방법입니다. 당신이 더 어떤 이유로 포함 된 모든 것을 유지하려면, 당신은 인생 사용할 수 있습니다

//test in chrome_v36 only 
var G = function() { 
}; 
G.prototype.g1 = function() {}; 

var E = function() { 
}; 
E.prototype = Object.create(G.prototype); 
E.prototype.e2 = function() {}; 

var F = function() { 
}; 
F.prototype = Object.create(E.prototype); 
F.prototype.f3 = function() {}; 

var xx = new F(); 
console.log(xx); //F {f3: function, e2: function, g1: function} 
console.log("xx instanceof E:___" + (xx instanceof E)); // true 
console.log("xx instanceof F:___" + (xx instanceof F)); // true 
console.log("xx instanceof G:___" + (xx instanceof G)); // true 

: Object.create() 오히려 new 이상 사용주의 그러나

//test in chrome_v36 only 
var G = (function() { 
    var g = function() { 
    }; 

    g.prototype.g1 = function() {}; 

    return g; 
})(); 

var E = (function() { 
    var e = function() { 
    }; 

    e.prototype = Object.create(G.prototype); 
    e.prototype.e2 = function() {}; 

    return e; 
})(); 

var F = (function() { 
    var f = function() { 
    }; 

    f.prototype = Object.create(E.prototype); 
    f.prototype.f3 = function() {}; 

    return f; 
})(); 

를, 난 정말이 표시되지 않습니다 이렇게하는 것이 유익하다. 적어도이 단순한 예는 아닙니다.