JavaScript OOP: classical implementation odd -
ok, i've revised of techniques implement inheritance in javascript oop. java programmer, i'm interested in classical approach here's problem; want create animal
class (i know it's not real class, let me use term) this:
function animal(name){ this.name = name; } animal.prototype.getname = function() { return this.name; }
it important note concrete class in first intention, want instantiate it, not use superclass. may create several animal
instances, each 1 own name.
a possible way extend class following:
function cat(name, owner) { this.name = name; this.owner = owner; } // alternative 1: cat.prototype = object.create(animal.prototype); // alternative 2: cat.prototype = new animal('lola'); // end of alternatives cat.constructor.prototype = cat; cat.prototype.jump = function() { alert(this.name + " jumping"); }
with alternative 1 inherit methods of superclass, in fact need redefine name
property in cat. alternative 2 nothing changes, have 1 more object in chain holds name
property that's quite useless: it's same cat
instances.
the point here i've written animal
class own name , throw away extend it. i'd have though way inherit both properties , methods and, of all, i'd able reuse animal
constructor.
the traditional way inherit properties of base constructor follows:
function cat(name, owner) { animal.call(this, name); // call base constructor this.owner = owner; } cat.prototype = new animal; cat.prototype.constructor = cat; cat.prototype.jump = function () { alert(this.name + " jumping"); };
the above code equivalent following class in other languages:
class cat extends animal { constructor(name, owner) { super(name); this.owner = owner; } jump() { alert(this.name + " jumping"); } }
the new way inherit properties same, save replace new animal
object.create(animal.prototype)
. reason prefer new way because:
- calling
new animal
unnecessary overhead.cat
constructor calls again anyway. - calling
new animal
might not return blank object. might add properties object. - we don't know arguments call
new animal
yet. hence makes no sense call it.
thus preferred way of inheritance now:
function cat(name, owner) { animal.call(this, name); // call base constructor this.owner = owner; } cat.prototype = object.create(animal.prototype); cat.prototype.constructor = cat; cat.prototype.jump = function () { alert(this.name + " jumping"); };
note it's important call base constructor because may initialization necessary instance work properly.
if you're interested in writing javascript code in classical style take @ following answer describes prototype-class isomorphism. following code taken above answer:
function class(prototype, base) { switch (typeof base) { case "function": base = base.prototype; case "object": prototype = object.create(base, descriptorof(prototype)); } var constructor = prototype.constructor; constructor.prototype = prototype; return constructor; } function descriptorof(object) { return object.keys(object).reduce(function (descriptor, key) { descriptor[key] = object.getownpropertydescriptor(object, key); return descriptor; }, {}); }
using class
function can define pseudo-classes in javascript follows:
var animal = class({ constructor: function (name) { this.name = name; }, getname: function () { return this.name; } }); var cat = class({ constructor: function (name, owner) { animal.call(this, name); this.owner = owner; }, jump: function () { alert(this.name + " jumping"); } }, animal);
there other ways inheritance in javascript well. suggest read blog post on why prototypal inheritance matters understand more inheritance in javascript.
Comments
Post a Comment