L'extrait de héritage de Javascript de John Resig est-il obsolète?

Je cherche un moyen simple de créer deux classes, l'une héritant de l'autre, et l'enfant redéfinissant l'une des méthodes des parents, et à l'intérieur de la nouvelle méthode, en appelant les parents.

Par exemple, avoir une classe Animal and Dog , où la classe Animal définit une méthode makeSound() qui établit comment produire un son, lequel Dog supprime alors dans sa propre méthode makeSound() pour faire un "woof", mais aussi makeSound() Animal's makeSound() pour sortir ce woof.

J'ai regardé le modèle de John Resig ici , mais il utilise la propriété arguments.callee native qui est apparemment dépréciée dans le script ECMA 5. Cela signifie-t-il que je ne devrais pas utiliser le code de John Resig?

Quelle serait une façon simple et simple d'écrire mon code animal / chien en utilisant le modèle d'héritage prototype de Javascript?

Est-ce que cela signifie que je ne devrais pas utiliser le code de John Resig?

Correct, pas lorsque vous utilisez ES5 en mode strict. Cependant, il peut être facilement adapté:

 /* Simple JavaScript Inheritance for ES 5.1 * based on http://ejohn.org/blog/simple-javascript-inheritance/ * (inspired by base2 and Prototype) * MIT Licensed. */ (function(global) { "use strict"; var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; // The base Class implementation (does nothing) function BaseClass(){} // Create a new Class that inherits from this class BaseClass.extend = function(props) { var _super = this.prototype; // Set up the prototype to inherit from the base class // (but without running the init constructor) var proto = Object.create(_super); // Copy the properties over onto the new prototype for (var name in props) { // Check if we're overwriting an existing function proto[name] = typeof props[name] === "function" && typeof _super[name] == "function" && fnTest.test(props[name]) ? (function(name, fn){ return function() { var tmp = this._super; // Add a new ._super() method that is the same method // but on the super-class this._super = _super[name]; // The method only need to be bound temporarily, so we // remove it when we're done executing var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, props[name]) : props[name]; } // The new constructor var newClass = typeof proto.init === "function" ? proto.hasOwnProperty("init") ? proto.init // All construction is actually done in the init method : function SubClass(){ _super.init.apply(this, arguments); } : function EmptyClass(){}; // Populate our constructed prototype object newClass.prototype = proto; // Enforce the constructor to be what we expect proto.constructor = newClass; // And make this class extendable newClass.extend = BaseClass.extend; return newClass; }; // export global.Class = BaseClass; })(this); 

Chaîne de prototypes avec Object.create () + attribuer un constructeur

 function Shape () { this.x = 0; this.y = 0; } Shape.prototype.move = function (x, y) { this.x += x; this.y += y; }; function Rectangle () { Shape.apply(this, arguments); // super constructor w/ Rectangle configs if any } Rectangle.prototype = Object.create(Shape.prototype); // inherit Shape functionality // works like Rectangle.prototype = new Shape() but WITHOUT invoking the constructor Rectangle.prototype.constructor = Rectangle; var rect = new Rectangle(); rect instanceof Rectangle && rect instanceof Shape // returns true 

À partir de Object.create documentation

Informations sur le nouveau mot-clé

C'est quelque chose que j'ai proposé pour l'héritage en utilisant le chaînage, tout en permettant à _super de fonctionner.

 /** * JavaScript simple inheritance * by Alejandro Gonzalez Sole (base on John Resig's simple inheritance script) * MIT Licensed. **/ (function (){ var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.* /; function Class(){}; function inheritClass(superClass){ var self = this; function Class(){ if (!initializing && typeof this._constructor === 'function') this._constructor.apply(this, arguments); } Class.prototype = superClass.prototype; Class.prototype._constructor = superClass; Class.prototype.constructor = Class; Class.extend = extendClass; //currenlty if you inhert multiple classes it breaks Class.inherit = inheritClass; return Class; }; function extendClass(prop) { var self = this; var _super = self.prototype; function Class(){ if (!initializing && typeof this._constructor === 'function') this._constructor.apply(this, arguments); } initializing = true; var prototype = new self(); initializing = false; for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function(name, fn){ return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })(name, prop[name]) : prop[name]; } Class.prototype = prototype; Class.prototype.constructor = Class; Class.extend = extendClass; Class.inherit = inheritClass; return Class; }; Class.extend = extendClass; Class.inherit = inheritClass; })(); //EXAMPLE function Person(){ this.name = "No name"; console.log("PERSON CLASS CONSTRUCTOR") } Person.prototype.myMethod = function (t){ console.log("MY PERSON", t, this.name); return -1; } var TestPerson = Class.inherit(Person).extend({ _constructor: function(){ this._super(); this.name = "JOhn"; console.log("TEST PERSON CONSTRUCTOR"); }, myMethod: function (t){ console.log("TEST PERSON", t, this.name); return this._super(t) } } var test = new TestPerson(); console.log(test.myMethod("BA")); 

Je l'ai testé sur mon wrapper Pixi https://github.com/guatedude2/pixijs-cli jusqu'à maintenant, ça m'a bien fonctionné.

Le seul problème que j'ai rencontré avec cette approche est que vous ne pouvez hériter qu'une seule fois. Si vous exécutez hériter à nouveau, il remplacera l'héritage précédent.

Je préfère la façon dont TypeScript génère une forme d'héritage (Sélectionnez l' héritage simple dans la liste déroulante). Celui-ci n'utilise pas arguments.callee , mais un prototype __extends .

 var __extends = this.__extends || function (d, b) { function __() { this.constructor = d; } __.prototype = b.prototype; d.prototype = new __(); }; var Animal = (function () { function Animal(name) { this.name = name; } Animal.prototype.move = function (meters) { alert(this.name + " moved " + meters + "m."); }; return Animal; })(); var Snake = (function (_super) { __extends(Snake, _super); function Snake(name) { _super.call(this, name); } Snake.prototype.move = function () { alert("Slithering..."); _super.prototype.move.call(this, 5); }; return Snake; })(Animal); var Horse = (function (_super) { __extends(Horse, _super); function Horse(name) { _super.call(this, name); } Horse.prototype.move = function () { alert("Galloping..."); _super.prototype.move.call(this, 45); }; return Horse; })(Animal); var sam = new Snake("Sammy the Python"); var tom = new Horse("Tommy the Palomino"); sam.move(); tom.move(34);