Javascript用のシンプルなRubyスタイルの継承

今日はgithubでかなり面白い要旨に出会いました。

彼のコードは次のとおりです。
/*
* 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 );




使用例も示します。
//

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();



JavaScript構文とは違いますか?

仕組み:


実行順序について少し:
var a = {valueOf: function (){alert(2)}}
var b = function (){alert(1);}
a << b();


このコードを実行してみてください。
最初にb関数が実行され、次に(valueOf関数を介して)値が計算されます。

したがって、あなたが書くとき:
def( 'a' ) ({a:1});
def( 'b' ) << a ({b:1});


最初に、最初の行で作成された関数aが引数{b:1}で呼び出されます。 この時点で、 deferredは、補足が必要なクラスと、補足されたクラスの属性/メソッドのセットを記述します。
次にdef( 'b')が実行されますValueOfdeferredからクラスと「プラグイン」を取得し、aに基づいてクラスを作成 、それに属性/メソッドを書き込みます。

すべてが非常にシンプルで簡潔です!
この履歴へのリンクを提供してくれたjdaltonに感謝します!

PS
翻訳および補足

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


All Articles