JavaScriptとLuaを比べてみた
最近ゲームを作る時に、Luaを使ってプロトタイプを作成しています。Luaはゲーム業界でよく知られている言語で、ゲーム中のイベントやAIなどのロジカルはLuaで組むことが多いです。
一ヶ月近くLua使ってみたら、JavaScriptとかなり似ている部分があるなと思いました。JavaScriptとLuaともEvent Drivenに適切な言語で、プロトタイプを作るには結構便利で効率がいいです。
この二つの言語正直あまり関係ないですが、自分はJavaScriptをよく使っているので、Luaを書いてる時になんとなくJavaScriptと比較したくなります。
変数
JavaScriptでは変数の宣言はvar
を使いますが、Luaではlocal
を使います。
LuaとJavaScriptは変数の型がなくて、言語自身がそれを面倒を見てもらいます。Luaではlocal
を使わずに変数を宣言すると、グロバール変数になってしまいます。ブラウザバージョンのJavaScriptも同じ挙動です。
JavaScriptとLua両方ともできるだけグロバール変数を使わないように。特にLuaではグロバール変数にアクセスするのはパフォーマンスコストが高いです。
function
LuaとJavaScriptともfunction
があります。一番大きいな違いは、JavaScriptのfunction
の優先順位は一番高いが、Luaはそうではないです。例で説明すると:
JavaScript
Hello(); // Helloの定義は次に来るが、問題なくコールされます。
function Hello() {
console.log('Hello World');
}
Lua
Hello() // 上記のJavaScriptと同じく、Helloの定義が次に来るが、エラーです。
local function Hello()
print('Hello World')
end
もちろん、LuaとJavaScriptとの文法も若干違います。あとで説明します。
JavaScriptのfunction
はスクリプトが実行される前に、定義の順番と関係なく、一番最初に解析されます。Luaは定義の順番に実行されます。
文法の違い
Luaの文法は若干くせがついています。もちろん慣れたらいいんですが、未だに自分はLuaのend
文法に慣れていないです。
if文
JavaScriptはCスタイルの文法を使っています。
var ok = true;
if (ok) {
console.log('OK');
} else {
console.log('Ops');
}
Luaの場合:
local ok = true
if ok then
print('OK')
else
print('Ops')
end
Luaでは
;
をあまり使わないです。JavaScriptも;
を使わなくて特に問題ないですが、コーディング習慣としてはよくないので、個人的にはあまりおすすめしません。
Luaの
then
とend
は本当に書き忘れがちです。
演算子
Luaでは!=
を使わず、~=
と書きます。これ間違えやすいです。Luaでは否の演算子が!
ではなくnot
です。これは他の言語と比べたら結構癖が強いです。あと||
と&&
がor
とand
になります。英語圏の人間にとっては読みやすいかもしれないですが、他の言語から来た人間は慣れるには少し時間かかりますね。
そして、他の言語でよくある++
や+=
もLuaでは使えないです。素直にi = i + 1
を書くしかないです。
JavaScriptはJSONのフォーマットでオブジェクトが作成できます:
var obj = {
name : 'hello',
target : 'world',
say : function(what){
return 'You said:' + what;
}
};
Luaでは、meta tableというデータ構造を使っています。JSONに非常に似てるが、:
の代わりに=
を使います:
local obj = {
name = 'hello',
target = 'world',
say = function(what)
return 'You said:' .. what
end
}
この=
を:
に間違えて書いてもなかなか気づかない時があるので、つらいです(笑)。
OOP
JavaScriptとLuaにはClass
というコンセプトがないですが、それぞれ自分の独自の方法でClass
らしいオブジェクトが作れます。
JavaScriptはprototype
を利用してClass
を作っています:
var MyClass = (function(){
// construct
function MyClass(params)
{
this.params = params || {};
}
// instance method
MyClass.prototype.getName = function()
{
return this.params.name || 'none';
}
// static method
MyClass.create = function(params)
{
return new MyClass(params);
}
reutrn MyClass;
})();
var my_class = MyClass.create({ name : 'Hello' });
console.log(my_class.getName()); // Hello
Luaの場合は
local myClass = {}
// constructor
function myClass:new(params)
local p = params or {}
setmetatable(p, self)
self.__index = self
return p
end
// instance method
function myClass:getName()
return self.name or 'none'
end
// static method
function myClass.create(params)
return myClass:new(params)
end
local my_class = myClass.create({ name = 'Hell' })
print(my_class:getName()) // 'Hello'
Lua一番ややこしいところは.
と:
の区別です。理論的には簡単ですが、なんか文法が中途半端ですごい間違えやすいです:
function Class.method(self)
return self.name
end
function Class:method()
return self.name
end
// 上記の二つのメーソドは同じものです。「:」を使うと、第一引数にオブジェクト自身のインスタンスが渡され、メソード内selfで呼び出せます。
まとめ
この記事は単純に趣味でLuaとJavaScriptを比較してみただけです。あまり意味ないかもしれないけど、JavaScript経験者がLuaを学べる参考になると嬉しいです。