Javascript __proto__ does not produce the same effects as inheriting "prototype"
The main reason for using " proto " this time is trying to keep the definition of inheritance inside the function definition:
set up inheritance function on sides def, only works for functions that only access "public fields" via "this.xxx", and Inheriting_FuncDef must have extended knowledge of SuperFuncDef, other sensible "public fields" 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" it seems the only drawback is that the "instancof" test cannot be correct, otherwise it can be used. but "instancof" incorrectness is a serious flaw.
//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
therefore, any method cannot give perfect results. and I think that Funcref.prototype = new superFuncref () method for setting inheritance basically doesn't work for me.
and the only reason I am doing Object.setPrototypeOf (this, the new SuperFuncRef ()); because I want every "instancof" condition to be true, otherwise I would do SuperFuncRef (). apply (this), first copy the whole function to "this", then do a local override. hence the new F () is only an instance of F, this is not what I wanted.
Thanks for your attention. if you don’t like it, or don’t think it’s worth it, leave it alone, don’t waste any more time on down_vote, I’m on the verge, or you can teach me English grammar by commenting below. I will reformat it over and over until you are satisfied, whether you give an answer or not.
source to share
an answer like sort is presented in this link, although does not specifically answer this question, the mechanism is the same:
fooobar.com/questions/2170657 / ...
The hard, sad truth that I don't know about before is this: every constructor instance has the same constructor, hence the same constructor.prototype, and a single "proto_instance" for each FuncDef instance cannot be faked:
function ClassNameHere (){}
var x = new ClassNameHere ();
var x2 = new ClassNameHere ();
console.log(x.__proto__===ClassNameHere.prototype)// true.
console.log(x.__proto__===x2.__proto__)// true.
so there is no way to only use "javascript inheritance" to create a similar java_Class function: (private_fields, inheritance)
the difficult, sad truth is that I didn't know before that, indeed, "javascrpit inheritance" only needs to be set once.
the solution is using SuperFuncRef.call (this) to copy all SuperFunc methods and create a new scope for those copied methods and then override impl. meanwhile, use "light_weight instance of SuperFunc" to "fake" / express "inheritance_relationship / chain"
I don't know if this is evil code, but the result is what I wanted:
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
source to share
Why are you trying to do everything inside the constructor? It is ineffective and has no purpose. You also shouldn't touch __proto__
unless you have the rare need to do so.
Here's an orthodox way to set up inheritance (and not have a separate copy of each member function at runtime). Please note the use Object.create()
, not 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 whatever 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 this. At least not for this simplified example.
source to share
Self-contained isolated inheritance with prototype assignment abuse? You can do it.
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
Consider this example as an exercise only - the path is highly discouraged (since the purpose of the prototype is there).
source to share