Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript __proto__ don't produce the same effects that "prototype" inheritance does

the main reason to use " proto " this time is trying to keep inheritance definition inside function definition:

setup the inheritance out side function def, only works for functions that only access "public fields" through "this.xxx" , and the Inheriting_FuncDef must have the extending knowledge of SuperFuncDef , other wise the "public fields" would happen to collide:

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

for the "improved version",seems the only drawback is that : the "instancof" test can not be correct , otherwise ,it is usable. but the "instancof" incorrectness is a major drawback.

//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

so either way is can't produce the perfect result. and i think the "Funcref.prototype=new superFuncref()" way for inheritance setup basically don't work for me.

and the only reason i do Object.setPrototypeOf(this,new SuperFuncRef()); is because i wanna all "instancof" clause to be true, otherwise , i would do SuperFuncRef().apply(this), copy all the function into "this" first,then do the local override. hence the new F() is only a instanceof F, that is not what i wanted.

thanks for you attention. if you don't care it , or think not worth it , please leave it alone,don't waste more time to down_vote it , i am at the edge of , or you can teach me English grammar by commenting below it . i will re-format it again and again till you satisfy ,despite you give a answer or not.

like image 791
Johnny Avatar asked Jul 25 '26 04:07

Johnny


1 Answers

Why are you trying to do everything inside the constructor? That's inefficient and serves no purpose. You also shouldn't be touching __proto__ unless you have some rare need to do so.

Here is an orthodox way to set up inheritance (and not have a separate copy of every member function during execution). Note the use of Object.create() rather than new:

//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

If you want to keep everything more contained for some reason, you can use an IIFE:

//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;
})();

However, I really don't see any benefit in doing this. At least not for this simplistic example.

like image 67
JLRishe Avatar answered Jul 27 '26 18:07

JLRishe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!