JavaScriptとLuaの微妙な違い[終了]


121

私は単にJavaScriptが大好きです。それはとてもエレガントです(恋に落ちたファンボーイが背後でため息をつくような静かな音を想像してください)。

それで、最近私はlöve2dを介してLuaと遊んだフレームワーク(素晴らしい!)-そして、Luaも素晴らしいと思います。彼らは私が見ているように、これらの2つの言語は非常によく似ています。

のような明らかな違いがあります

  • 構文
  • 問題ドメイン
  • 図書館
  • タイプ(少し)

しかし、より微妙なものはどれですか?Luaでわずかに異なる動作をするJavaScriptコーダーが当たり前と思われるものはありますか?ある言語の経験豊富なコーダーが他の言語を試してみて明らかではない落とし穴はありますか?

例:Luaでは、配列とハッシュは分離されていません(テーブルのみがあります)-JavaScriptでは、数値配列とハッシュオブジェクトです。まあ、これはより明白な違いの1つです。

しかし、変数のスコープ、不変性などの違いはありますか?


8
全体的な比較を求めていて、偶然にここで終わった私のように、以下はすばらしい概要です:phrogz.net/lua/LearningLua_FromJS.html
Tao

:これは、あなたが始めるために知っておく必要がありますすべての違いを説明する3回シリーズでoreilly.com/learning/...
のcharAt

回答:


189

さらにいくつかの違い:

  • Luaコルーチンをネイティブでサポートしています。
    • 更新:JSはジェネレーター内にyieldキーワードを含み、コルーチンをサポートします。
  • Lua 比較演算子の型を変換しません。JSでは、juggleとだけ入力===して!==ください。
  • Luaには指数演算子(^)があります。JSはしませんJSは、3項条件演算子(?:vs and/or)を含むさまざまな演算子を使用します。5.3&以降|では、ビットごとの演算子(、、などvs メタメソッド)を使用します。
    • 更新:JSに指数演算子が追加されました**
  • JSには増分/減分、タイプ演算子(typeofおよびinstanceof)、追加の代入演算子、および追加の比較演算子があります。
  • JS=====!=及び!==オペレータがより低い優先順位です>>=<<=。Luaでは、すべての比較演算子は同じ優先順位です。
  • Lua末尾呼び出しをサポートしています
  • Lua は変数のリストへの割り当てをサポートしていますJavascriptではまだ標準ではありませんが、MozillaのJSエンジン(およびある程度までOperaのJSエンジン)は、JS 1.7(Firefox 2の一部として入手可能)以降、「破壊的な割り当て」という名前で同様の機能をサポートしています。JSでの解体は、関数定義と呼び出しループ初期化子など、割り当て以外のコンテキストで使用できるため、より一般的です。破壊的な割り当ては、しばらくの間、ECMAScript(Javascriptの背後にある言語標準)への提案された追加でした。
    • 更新:解体(および解体の割り当て)がECMAScriptの仕様の一部になりました-すでに多くのエンジンに実装されています。
  • Luaの、あなたができる演算子をオーバーロードします
  • Luaの、あなたが環境を操作することができますgetfenvし、setfenv中にLuaの5.1または_ENVLuaの5.25.3
  • ではJS、すべての機能は可変長です。でLuaの、機能はしなければならない明示的に可変引数として宣言されました
  • ForeachJSオブジェクトのプロパティをループします。foreachののLUA(キーワードを使用for)イテレータをループ、より一般的です。
    • 更新:JSには現在Iterableもあり、その多くはのような通常のデータ構造に組み込まれていArrayます。これらはfor...of構文でループできます。通常のオブジェクトの場合、独自のイテレータ関数を実装できます。これにより、Luaにかなり近づきます。
  • JSにはグローバルスコープと関数スコープがあります。Luaにグローバルスコープとブロックスコープがあります。制御構造(例えばifforwhile)新しいを導入ブロックを

    • スコーピングルールの違いにより、クロージャーによる外部変数の参照(Luaの用語では「upvalues」と呼ばれます)は、LuaとJavaScriptでは異なる方法で処理されます。これは最も一般的forループ内のクロージャーで発生し、一部の人々を驚かせます。Javascriptを、身体のforいずれかの機能は、すべての参照にループ本体内で宣言してループは、新しいスコープを導入しないと同じ外側の変数を。Luaでは、forループを繰り返すたびに、ループ変数ごとに新しいローカル変数が作成されます。

      local i='foo'
      for i=1,10 do
        -- "i" here is not the local "i" declared above
        ...
      end
      print(i) -- prints 'foo'

      上記のコードは次と同等です。

      local i='foo'
      do
        local _i=1
        while _i<10 do
          local i=_i
          ...
          _i=_i+1
        end
      end
      print(i)

      結果として、個別の反復で定義された関数は、参照されるループ変数ごとに異なるアップ値を持ちます。Luaでのクロージャーの実装に対するNicolas Bolaの回答も参照してくださいおよび「ループ変数に対するクロージャーの正しいセマンティクスは何ですか」および「ジェネリックのセマンティクス」。

      更新:JSには現在ブロックスコープがあります。ブロックスコープで定義された変数、letまたはconstブロックスコープを尊重する変数。

  • JSの整数リテラルは8進数にすることができます。
  • JSは明示的なUnicodeサポートを備えており、内部で文字列はUTF-16でエンコードされています(したがって、これらはバイトのペアのシーケンスです)。"pâté".toUpperCase()"PÂTÉ")などのさまざまな組み込みJavaScript関数がUnicodeデータを使用します。Lua 5.3以降には、文字列リテラルのUnicodeコードポイントエスケープシーケンス(JavaScriptコードポイントエスケープシーケンスと同じ構文)とutf8UTF-8エンコーディングの基本的なサポートを提供する組み込みライブラリがあります。(コードポイントをUTF-8にエンコードし、UTF-8をコードポイントにデコードし、文字列内のコードポイントの数を取得し、コードポイントを反復するなど)。Luaの文字列は個々のバイトのシーケンスであり、任意のエンコーディングまたは任意のバイナリデータのテキストを含めることができます。Luaには、Unicodeデータを使用する組み込み関数はありません。の動作はstring.upperCロケールに依存します。
  • Luaのnotorandキーワードの代わりに使用されているJSさん!||&&
  • Lua~=「等しくない」を使用しますが、JSはを使用し!==ます。たとえば、if foo ~= 20 then ... end
  • Luaの5.3とアップの使用~に対し、バイナリビット単位のXORのため、JSの用途 ^
  • LUA、(以外の値の任意のタイプnilとはNaN)インデックステーブルに使用することができます。JavaScriptを、(記号を除く)すべての非文字列型はインデックスにオブジェクトを使用される前に文字列に変換されます。たとえば、次のコードの評価後の値はobj[1]なります"string one"が、、JavaScriptで"number one"のLuaで:obj = {}; obj[1] = "number one"; obj["1"] = "string one";
  • ではJS、割り当ては式として扱われますが、中のLuaそうではありません。このように、JSは、の条件で割り当てを可能にするifwhiledo whileのステートメントが、Luaはではないifwhilerepeat until声明。たとえば、if (x = 'a') {}は有効なJSですif x = 'a' do endが、無効なLuaです。
  • Luaはブロックスコープの機能変数、フィールドで機能を宣言するための糖衣構文を有し、および方法(local function() endfunction t.fieldname() endfunction t:methodname() end)。JSはこれらを等号(let funcname = function optionalFuncname() {}objectname.fieldname = function () {})で宣言します。

6
Luaでは、論理演算子(および、または)は引数の1つを返します。すべての関数は、任意の数のパラメーターで呼び出すことができます。ただし、必要な数に調整されます(... 'extra args'を使用する場合を除く)
Javier

1
@RCIX:luaconf.h(およびLua 5.2では、lparser.cおよびllimits.hも参照)。Lua 5.1およびLua 5.2の最大ローカル値/関数= 200。最大アップ値/関数= Lua 5.1では60、Lua 5.2では255(このカウントには、関数内で作成されたクロージャーによって「継承される」クロージャーも含まれます)。
dubiousjim

8
1ベースの配列をリストに追加できると思います。慣れていないとかなり面倒です。
Yann 2014

2
Luaではnilとfalseだけが偽です。たとえば、0はLuaでは真実ですが、jsでは真実ではありません。Unicodeサポートについて:Lua 5.3は明示的なUTF-8サポートを追加し、古いLuaバージョンは文字列に保持されているUTF-8バッファーに対応しています(たとえば、文字列検索パターンでUnicodeを使用できます)。UTF-8のJSサポートは完全ではありません。V8は内部で古い16ビット表現を使用しているため、Unicode文字列が(驚き!)サロゲートペアになってしまう可能性があります。ルアでは起こりません)。
タイラー

4
私はこのリストを愛していましたが、どうやって微妙なバグ~=を引き起こすことができるのかわかりません。構文エラーを引き起こす可能性がありますが、まったく微妙ではありません。
kikito 2015年

12

少なくとも1度は気付かれる2つの微妙な違い:

  • 等しくないは~=Lua で綴られています。JSでは!=
  • Lua 配列は1ベースです -最初のインデックスは0ではなく1です。
  • Luaでは、オブジェクトメソッドを呼び出すためにピリオドではなくコロンが必要です。†のa:foo()代わりに書くa.foo()

必要に応じてピリオドを使用できますが、self変数を明示的に渡す必要があります。a.foo(a)少し面倒に見えます。詳細については、Luaでのプログラミングを参照してください。


5
アノテーションにを使用すると、a.foo()xDで死亡したように見えます
DarkWiiPlayer

11

正直に言うと、違いをリストするよりも、JavaScriptとLuaに共通するものをリストする方が簡単です。どちらも動的に型付けされたスクリプト言語ですが、実際にはこれで十分です。完全に異なる構文、異なる独自の設計目標、異なる動作モード(Luaは常にバイトコードにコンパイルされ、Lua VMで実行され、Javascriptは異なります)、リストは続きます。


8
絶対に。非常に異なる目標には、クリーンな言語を使用するための高い優先順位が含まれます。Javascriptには多くの歴史的な手荷物があり、Luaは望ましくないものを継続的に放出しています。
ハビエル

3
+1。どちらもスクリプトに使用されているという事実(あまりに明白です)を除いて、それらがどのように似ているかさえまったくわかりません。
サーシャチェディゴフ2009年

13
-1(可能な場合)言語デザインの面では非常によく似ています。Luaは単により多くの機能を備え、より小さくなっています(より高速ですか?)。言語設計と実装の選択を混同していると思います。
jpc

ええ、どちらもプロトタイプOOPです(たとえそれがキーワードprototypeまたはオブジェクトオブジェクトの名前付けを使用して明示的に指定されていない場合でも、それがluaテーブルとまったく同じであるという事実にもかかわらず) 、宣言型開発など)、
Bojan Markovic

2
確かに、構文の違いがあり、それを表面的に見ると、言語が異なると結論付けるかもしれません。しかし、全く同じメインデータ型(オブジェクト/テーブル)とクラスとinherritanceを実装するのと同じ方法(何かその有する点で非常に少数の他の言語のシェアを)驚くほど近い精神でそれらを作ります。自明でないJSプログラムの設計は、Luaのプログラムの設計とほとんど同じです。
Alex Gian 2017

7

JavaScriptの配列とオブジェクトは、思っているよりも近くにあります。配列表記を使用して、それらのいずれかの要素を取得できます。また、配列に数値以外のインデックスを追加できます。個々の配列要素は何でも保持でき、配列は疎である場合があります。彼らはほぼ同じいとこです。


1
同じいとこを持つことはできますか?
jameshfisher 2011年

それらは同じデータ構造であり、唯一の違いは型記述子であるため、区別することができます。
リリス川

5
より正確なステートメントは次のとおりです。配列は、「長さ」メンバーの特別な動作を持つオブジェクトです。
tzenes

@eegg:確かに、キャシーとパティ
outis

3

頭の上から

ルア...

  1. コルーチンをサポート
  2. テーブルのキーとして文字列/数値だけに制限はありません。すべてが機能します。
  3. エラー処理はやや不格好です。何も処理しないか、pcallメソッドを使用します
  4. 字句スコープの違いについて何か読んだと思います。Luaの方が優れていると思います。
  5. Luaでの正規表現のサポートを正しく思い出した場合、制限があります

Luaに字句スコープがあります。JavaScriptには関数スコープのみがあります。MozillaとRhinoでは、「var」の代わりに「let」を使用して適切な字句スコープを取得できるようになりました。しかし、それはまだ移植可能ではありません。
ハビエル

1
Luaの標準文字列ライブラリには、限られたパターンマッチング関数が含まれています。しかし、完全な文法で簡単に使用できる、はるかに強力なマッチングシステムを提供するLPEG(ライブラリ)もあります。
ハビエル

私は、LUAには「より良い」レキシカルスコープがあり、javascriptはないということではないと述べました。
ジッタ

1
LPEGは、コア正規表現のサポートを意味し、追加のライブラリは私に限られている
ジッタ

文字列キーと数値キーの間に多少の制限があります。同じテーブルで両方を使用すると、#は番号付きインデックスの量ではなくテーブル長を返すため、辞書エントリと競合するため、非常に速く混乱します(列挙後にnilのインデックス付け)テーブルインデックス)
Weeve Ferrelaine 2014年

3

私はこの質問と提供された回答が気に入りました。2つの言語が私よりも似ているように見える追加の理由:

どちらも関数を変数に割り当て、オンザフライで関数を作成し、クロージャを定義できます。


1

LuaとJavaScriptはどちらもプロトタイプのベース言語です。


1
これは、2つの言語の明らかな類似点です。これと、主要なデータ型としてのテーブル/ハッシュの使用です。Javascriptプログラムを慣用的に開発する場合は、Luaの場合とほとんど同じアプローチをとります。他の言語では同じことをしません(プロトタイプの継承とテーブルに基づく言語でない限り)。これは非常に類似しています。残りの部分、マイナー構文の詳細などは、比較するとかなり見識があります。
Alex Gian 2017年

1
重要な違いは、Jaavscriptはコルーチンをサポートしておらず、Cとあまり密接に結合しておらず、組み込み言語としてはあまり適していないことです。(JavaScriptでプログラムされているどのように多くのマイクロコントローラ?)Javascriptが従来の落とし穴とWATS(のトンで、また非常に厄介であるdestroyallsoftware.com/talks/wat) - 1:40から。ルアはかなりの質素な規律を課してきた。もちろん、JavaScriptはブラウザーで非常に強力です。
Alex Gian 2017年

1

テストにより、現在のJavaScriptもオブジェクト、または少なくともluaのような論理式からの文字列を返すことがわかります。

function nix(){
    alert(arguments[0]||"0");
} 
nix();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.