comprender el emulador de clase simple en JavaScript
Frecuentes
Visto 134 veces
2
Recently I started to learn a bit more advanced JavaScript (as far I only used jQuery for some simple tasks) and bought a book of Alex MaxCaw "JavaScript Web Applications". The first chapter treats about creating simple class emulator. I understand almost everything except for two lines of code marked with comments down below:
var Class = function(parent) {
var _class = function() {
this.init.apply(this, arguments);
};
if(parent) {
var subclass = function() {};
subclass.prototype = parent.prototype;
_class.prototype = new subclass();
};
_class.prototype.init = function() {};
_class.fn = _class.prototype;
//????
_class.fn.parent = _class;
//????
_class._super = _class.__proto__;
return _class;
};
Can anyone tell me what is purpose of these two lines? I'll be very thankfull.
2 Respuestas
3
Walking through the code:
- Class is defined as a function that calls init with the arguments provided it. This means you can call it with standard constructor syntax using
new
p.ej.var instance = new Thingy()
y obtener elinit
function called with the properthis
. - If you pass a parent class in, your class gets that class's
prototype
property added to the prototype chain of a new empty object which it uses as suprototype
property. A more succinct way of doing this in modern browsers is_class.prototype = Object.create(parent.prototype);
- Programas de
init
function is defined. This should likely be overridden with more useful initialization code after a_class
instance is created (or the code should be changed to allow the passing in of aninit
function when you create a Class... or allow the instance to walk the prototype chain to look for otherinit
funciones. _class.fn
is created to provide a reference to the_class
constructor's prototype function._class.fn.parent
is created to provide a reference back to the constructor. This may be useful if you are applying the prototype in some other context and want a reference back to the prototype's constructor._class._super
is assigned the internal, non-standard__proto__
property of the constructor. Remember that constructors are functions and, in Javascript, functions are objects. This means they have their own internal prototypes. The earlier references toprototype
Fuck Cancer. the prototype assigned to objects created with this constructor NOT the constructor's prototype itself. All functions inherit from Function.prototype, which is where they getbind
,apply
, etc._super
in this case is just a reference toFunction.prototype
.
As to when this type of _super
is used, one could imagine doing the following:
function Maker(){ //this will be called as a constructor, ie. with new
var fun = function(){}; //Make a function
fun.__proto__ = this.__proto__; //yuck. Set the function's this value to the instance
return fun; //return the function
}
Maker.prototype={say:function(){console.log("Javascript is fun!.. And weird.")}};
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // undefined!!
Woah! What just happened?
In fact, you replaced your functions internal prototype with an Object. This allows you to build up interesting prototype chains and interact with both functions and objects in a similar way. Note, however, that the link with Function.prototype
has been severed, which is why we don't have access to bind
. However let's fix it with more prototype magic!
function FunctionConnector(obj){
for (var prop in obj){
if(obj.hasOwnProperty(prop){
this.prop=obj.prop
}
}
}
FunctionConnector.prototype=Function.prototype;
Maker.prototype=new FunctionConnector({say:function(){
console.log("Javascript is fun!.. And weird.")
}});
var fun = new Maker();
fun.say() //"Javascript is fun!.. And weird."
console.log(fun.__proto__) // Object{say:function}
console.log(fun.bind) // function bind(){ [native code] }
Now what is that FunctionConnector
? It takes an object and, when called as a constructor, returns an object that both has all the properties of the passed object AND inherits from Function.prototype
. As you can see, our access to bind
has returned (Of course we also could have made do with our original implementation and just Function.prototype.bind.call
ed our way to victory).
With this new pattern in hand it may be clearer what _super
in your code does, namely it references the built in prototype of the _class
constructor you are making (In our example the instance of FunctionConnector
sería _super
). This reference could be used to patch the prototype at runtime, call methods with apply
or anything else you can due with a reference to an object.
This is, as you may have noticed a little hackish, especially since __proto__
is nonstandard. But it's also somewhat neat if you enjoy the patterns it allows. I'd recommend only doing something like this if you are very confident in your knowledge of Javascript inheritance, and perhaps not even then unless you are in charge of your entire code base.
Respondido el 27 de Septiembre de 13 a las 20:09
_class.fn.parent is now more clear to me. But I'm still a little bit confused about _super. I can't imagine situation in which I can use _super. Can you tell me a little more? Perhaps some example? - voronwe3
@voronwe3 added quite a bit - Wyatt
really helpful examples, and quite simple. Thanks a lot! - voronwe3
-1
Por lo que sé, fn
es solo un alias para el prototype
perfecta
Y sobre el _super
, that one is for referencing to the "class" from which you are inheriting
Here's more about the use of _super
and js inheritance: artículo
Respondido el 26 de Septiembre de 13 a las 21:09
_super is a property defined by John Resig in his extend model so that we can call parent's function in subclass. - uva_mao
@grape_mao ok, but I don't understand the purpose of _super in this simple piece of code I posted above. - voronwe3
@grape_mao this is unfortunately my problem. The code above is all what I have. Book doesn't supply examples of using this _super. But thanks for your attention and link you've provided. - voronwe3
@voronwe3 you thanked the wrong person...I'm actually the one who down-voted this answer because the _super in that article may be for different purpose. - uva_mao
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript prototypal-inheritance or haz tu propia pregunta.
JavaScript inheritance doesn't have
parent
ysuper
properties. This is just "faking" them, so you can use them. - gen_Eric