comprender el emulador de clase simple en JavaScript

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.

preguntado el 26 de septiembre de 13 a las 21:09

JavaScript inheritance doesn't have parent y super properties. This is just "faking" them, so you can use them. -

2 Respuestas

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 el init function called with the proper this .
  • 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 su prototype 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 an init function when you create a Class... or allow the instance to walk the prototype chain to look for other init 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 to prototype 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 get bind, apply, etc. _super in this case is just a reference to Function.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.called 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

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 or haz tu propia pregunta.