2

So, we can use javascripts native implementation of Object.create to sorta mimic prototype's Class.create.. BUT, there is the concept of $super.

here is the definition:

The $super argument in method definitions

When you override a method in a subclass, but still want to be able to call the original method, you will need a reference to it. You can obtain that reference by defining those methods with an extra argument in the front: $super. Prototype will detect this and make the overridden method available to you through that argument. But to the outside world, the Pirate#say method still expects a single argument. Keep this in mind.

Here is their example:

/** new, preferred syntax **/

// properties are directly passed to `create` method
var Person = Class.create({
  initialize: function(name) {
    this.name = name;
  },
  say: function(message) {
    return this.name + ': ' + message;
  }
});

// when subclassing, specify the class you want to inherit from
var Pirate = Class.create(Person, {
  // redefine the speak method
  say: function($super, message) {
    return $super(message) + ', yarr!';
  }
});

var john = new Pirate('Long John');
john.say('ahoy matey');

How does one go about mimicking this behavior with native JS or jQuery?

james emanon
  • 11,185
  • 11
  • 56
  • 97
  • 1
    Google Closure provides a mechanism like $super as well, using goog.inherits and goog.base. You can see the code here: http://docs.closure-library.googlecode.com/git/closure_goog_base.js.source.html. That might give you some ideas. – Herms Oct 07 '13 at 19:12
  • 1
    It may be worth looking into [klass](https://github.com/ded/klass), which is used by several Node projects. – Michael Tang Oct 07 '13 at 20:41

1 Answers1

2

Not with jQuery, as it does not have any tools for inheritance (other than $.extend).

You can simply refer the parent's prototype method in the native inheritance pattern, maybe combined with a revealing prototype module:

function Person(name) {
    this.name = name;
}
Person.prototype.say = function(message) {
    return this.name + ":" + message;
};

function Pirate(name) {
    Person.call(this, name);
}
Pirate.prototype = (function(super) {
    var p = Object.create(super, {
        constructor: {value: Pirate}
    });
    p.say = function(message) {
        return super.say.call(this, message) + ", yarr!";
    };
    return p;
})(Person.prototype);
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • let me review this. Looks good. thank you very much. Bergi, I read thru some of your others posts. You seem to have a very excellent grasp of Javascripts prototype motif and such.. how did you come to such an understanding? Books, blogs etc.. ? – james emanon Oct 07 '13 at 22:50
  • Bergi - can you tell me why you use this and what for: constructor: {value: Pirate} – james emanon Oct 07 '13 at 23:29
  • Check [what is the constructor property used for](http://stackoverflow.com/questions/12622137/what-is-the-constructor-property-really-used-for) and how [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) uses [property descriptors](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#Description). It might have been easier to do `p = Object.create(super); p.constructor = Pirate;`. – Bergi Oct 08 '13 at 00:03
  • I haven't read/found any good books on JS. I've gained my knowledge on Stackoverflow, MDN, by reading the language spec, and maybe some blog posts. – Bergi Oct 08 '13 at 00:06
  • Bergi - hopefully you see this. What is the diff from what you put and the following. Is there any shortcomings with the following. var p = {}; p.say = function(message) {return $super.say.call(this, message) + ", yarr!"}; – james emanon Oct 08 '13 at 23:47
  • Without `Object.create` it's not inheriting. That doesn't matter for the `say` method, but all non-overwritten methods of `Person.prototype` would not be available and also `p instanceof Person` or `(new Pirate) instanceof Person` would yield false. – Bergi Oct 08 '13 at 23:51