JavaScriptとLuaのクラス継承
4350 ワード
javascript自身は外観から対象に向けたプログラミング言語ですが、継承方式を明確に提供していません.二十数年の間に、多くの達人がアナログ継承の実現を提供しています.
主なものは、相手を偽って、call/apply、prototype、及び深度コピーなどです.ネット上にはこのような教程がたくさんあります.ここではこれらの実現を必要としません.私のチームがやっているプロジェクトは、jsとluaを使って同じAPIインターフェースを実現して、jsとluaのシームレスな切り替えを実現します.したがって、このような継承案を実現することが重要です.みなさんのご叱正をお願いします
Luaは、優れた動的言語であり、埋め込みのために生まれたものであり、シナリオとしてのみ使用されるならば、クラスの概念は必要ではないが、膨大な規模のコード量を構成するには、これは緊急の問題である.
javascript:
*initは、新たに生成されたクラスの構造関数です.
次に、私たちはこの二つのクラス関数を実現します.
1.jsでnew演算子を呼び出すと、実際には現在の構造関数の原型をコピーします.Luaにはnew演算子がありませんので、それをブロックします.
2.luaで方法の関連を実現したいのですが、主に2つの案を使っています.1つはコピーで、もう1つは元表を覆っています.indexインデックスは、コピーは、非常に良いアイデアです.または、非常に一般的な思想であり、継承の本質は、別の例を呼び出すことができます.このような場合は、コピーは、非常に完璧なソリューションです.簡単で荒っぽい、簡単で、荒っぽい、直接です.安定的で直接的な方案は往々にして論理を実現する最良の選択であるが、この過程が効率的であるためには、深い功力が必要であり、私はまだこのようなレベルに達していないと思います.indexインデックスを実装します
3.lua元表の_uindexインデックスは、よく考えてみると、そのメカニズムはjsのプロトタイプチェーンに似ています.つまり、Luaにjsのプロトタイプチェーンをシミュレートさせるのは比較的容易です.プロトタイプチェーンの方式はjavascriptの継承を実現するのもとても容易です.
上記3点に基づいて、コードを貼り付けます.
lua
次はjsの実現です.
Luuaにはキーワード'new'がないので、jsの実現はnewキーワードをシールドしました.ここでのjQueryの実現を参考にして、johnに敬意を表します.以下は具体的なコードです.
だから与えられた N,このNは何も実現されていません.また、任意のドメインをマウントしていません.Super.prototypeをN.prototypeにマウントするだけです.だから、new N()は、Super.prototypeを指すポインタに相当します.
メモリにはほとんど使われていません.newのキーワードを隠すには、工場の方法の実現を選択していません.jQueryを直接使う実現案です.
呼び出し:
主なものは、相手を偽って、call/apply、prototype、及び深度コピーなどです.ネット上にはこのような教程がたくさんあります.ここではこれらの実現を必要としません.私のチームがやっているプロジェクトは、jsとluaを使って同じAPIインターフェースを実現して、jsとluaのシームレスな切り替えを実現します.したがって、このような継承案を実現することが重要です.みなさんのご叱正をお願いします
Luaは、優れた動的言語であり、埋め込みのために生まれたものであり、シナリオとしてのみ使用されるならば、クラスの概念は必要ではないが、膨大な規模のコード量を構成するには、これは緊急の問題である.
javascript:
function Class(Super, init ){ //do }
lua: function Class(Super , init ) --[[do]] end
*Superは、新たに生成されたクラスの継承が必要な親類です.*initは、新たに生成されたクラスの構造関数です.
次に、私たちはこの二つのクラス関数を実現します.
1.jsでnew演算子を呼び出すと、実際には現在の構造関数の原型をコピーします.Luaにはnew演算子がありませんので、それをブロックします.
2.luaで方法の関連を実現したいのですが、主に2つの案を使っています.1つはコピーで、もう1つは元表を覆っています.indexインデックスは、コピーは、非常に良いアイデアです.または、非常に一般的な思想であり、継承の本質は、別の例を呼び出すことができます.このような場合は、コピーは、非常に完璧なソリューションです.簡単で荒っぽい、簡単で、荒っぽい、直接です.安定的で直接的な方案は往々にして論理を実現する最良の選択であるが、この過程が効率的であるためには、深い功力が必要であり、私はまだこのようなレベルに達していないと思います.indexインデックスを実装します
3.lua元表の_uindexインデックスは、よく考えてみると、そのメカニズムはjsのプロトタイプチェーンに似ています.つまり、Luaにjsのプロトタイプチェーンをシミュレートさせるのは比較的容易です.プロトタイプチェーンの方式はjavascriptの継承を実現するのもとても容易です.
上記3点に基づいて、コードを貼り付けます.
lua
local setmetatable, pairs = setmetatable, pairs;
function Class(Super, init)
local NEW = { fz = {} };--- , fz , js prototype .
NEW.__initialize = function(self, ...) --- .
local this = {}
for i, v in pairs(self) do ---- self
this[i] = v
end
if init then
init(this, ...); ---
end
return setmetatable(this, { --- .. NEW ,
__index = function(_, key) ------ NEW fz .
return NEW.fz[key]
end
});
end
setmetatable(NEW.fz, { --- .. NEW.fz ,
__index = function(_, key) ------ Super.fz , , nil.
return Super.fz and Super.fz[key] or nil;
end
});
return setmetatable(NEW, { --- __call , NEW hash .
__call = function(...)
return (...).__initialize(...); --- ..
end
});
end
呼び出し: local M = Class({}, function(self , a , b ) --- M , table
self.a = a
self.b = b
end)
M.fz.geta = function(self) --- geta .
return self.a;
end
local MM = Class(M , function(self, a , b) --- MM, M
self.a = a
self.b = b
end);
MM.fz.getb = function(self) --- getb.
return self.b
end
local mm = MM( "AAA" , "BBB"); --- MM mm
print(mm:geta()) --- "AAA"
print(mm:getb()) --- "BBB"
上记のコードは実现しますか?それとも比较的に简単です.子类は父类を受け継ぐことができます. fzの下のすべてのフィールド…次はjsの実現です.
Luuaにはキーワード'new'がないので、jsの実現はnewキーワードをシールドしました.ここでのjQueryの実現を参考にして、johnに敬意を表します.以下は具体的なコードです.
function Class(Super, init) {
var N = function () { // N .
};
N.prototype = Super.prototype; // N Super
var New = function () { // NEW
return new New.fz.initialize(arguments);
};
New.fz = New.prototype = new N(); // N NEW , fz.
New.fz.initialize = function (M) { // .
if (init) init.apply(this, M);
return this;
};
New.fz.constructor = New; // New.fz constructor NEW..
New.fz.initialize.prototype = New.fz; // ,jQuery .
return New;
}
なぜfunctionがあるのか説明してください. N: 前の文で述べたように、継承はprototype関連だけで、他の地域に対しては遮断すべきです.だから与えられた N,このNは何も実現されていません.また、任意のドメインをマウントしていません.Super.prototypeをN.prototypeにマウントするだけです.だから、new N()は、Super.prototypeを指すポインタに相当します.
メモリにはほとんど使われていません.newのキーワードを隠すには、工場の方法の実現を選択していません.jQueryを直接使う実現案です.
呼び出し:
var M = Class({}, function (a, b) {
this.a = a;
this.b = b;
});
M.fz.geta = function () {
return this.a;
};
var MM = Class(M, function (a, b) {
this.a = a;
this.b = b;
});
MM.fz.getb = function () {
return this.b
};
var mm = MM("AAA", "BBB");
print(mm.geta())
print(mm.getb())
相変わらずluaバージョンと同じコール方式です.