📜 ⬆️ ⬇️

Simple Ruby-style Inheritance for Javascript

Today I came across a rather interesting gist on github 'e.

Here is his code:
/*
* def.js: Ruby Javascript
*
* Copyright (c) 2010 Tobias Schneider
* This script is freely distributable under the terms of the MIT license.
*/
( function (global) {

// , ""
//
var deferred;

// ""
function addPlugins(plugins) {
augment( this .prototype, plugins);
return this ;
}

// "source" "destination"
function augment(destination, source) {
for ( var key in source) {
destination[key] = source[key];
}
}

// ,
function Subclass() { }

function def(klassName, context) {
context || (context = global);

// ( global)
var Klass =
context[klassName] = function Klass() {
//
if ( this != context) {
// "init" ,
// /
return this .init && this .init.apply( this , arguments);
}
//
// defer setup of superclass and plugins
// "deferred" "",
//
deferred._super = Klass;
deferred._plugins = arguments[0] || { };
};

// ,
Klass.addPlugins = addPlugins;

// ,
//
deferred = function (plugins) {
return Klass.addPlugins(plugins);
};

// valueOf
//
deferred.valueOf = function () {
// , "deferred"
var Superclass = deferred._super;

// -
// ,
// valueOf
if (!Superclass) return Klass;

//
Subclass.prototype = Superclass.prototype;
//
Klass.prototype = new Subclass;

// superclass
Klass.superclass = Superclass;
Klass.prototype.constructor = Klass;

// "", deferred
return Klass.addPlugins(deferred._plugins);
};

// deferred -
// , ,
return deferred;
}

// def
global.def = def;
})( this );




Also, an example of use is given:
//

def ( 'Person' ) ({
'init' : function (name) {
this .name = name;
},
'speak' : function (text) {
alert(text || ', ' + this .name);
}
});

def ( 'Ninja' ) << Person ({
'ask' : function () {
this .speak( ' , ?' );
}
});

var ninjy = new Ninja( '' );
ninjy.speak();
ninjy.ask();



It doesn't look like javascript syntax, right?
')

How does it work:


A little about the order of execution:
var a = {valueOf: function (){alert(2)}}
var b = function (){alert(1);}
a << b();


Try to execute this code.
First, the function b is executed, and then the value is calculated (through the function valueOf) a.

Thus, when you write:
def( 'a' ) ({a:1});
def( 'b' ) << a ({b:1});

.

First, the function a , created in the first line, is called with {b: 1} arguments. At this time, the class that needs to be added and the set of attributes / methods of the complemented class will be written to deferred .
Then def ('b'). ValueOf will be executed, the class and “plugins” from deferred will be taken , a class will be created based on a , and attributes / methods will be written to it.

Everything is pretty simple and concise!
Thanks jdalton for the link to this gist!

PS
Translated and updated version

Source: https://habr.com/ru/post/99080/


All Articles