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

翻訳および補足



All Articles