1. ホーム
  2. javascript

[解決済み] JavaScriptとLuaの微妙な違い [終了しました]

2022-07-22 11:08:46

質問

私は単純にJavaScriptが好きです。とてもエレガントです(背景には、恋するファンボーイの静かなため息の音を想像してください)。

というわけで、最近は löve2d フレームワーク (すばらしい!) を通して Lua に触れましたが、Lua もすばらしいと思います。私が思うに、この2つの言語は は非常に 似ています。

というように、明らかな違いがあります。

  • 構文
  • 問題領域
  • ライブラリ
  • タイプ (少し)

とありますが、もっと微妙なものはどれでしょうか?JavaScriptのコーダーが当たり前のように使っているものが、Luaではほんの少し違っていることはないでしょうか。一方の言語の経験豊富なコーダーが、もう一方の言語を試してみてもわからないような落とし穴があるのでしょうか?

例えば、Luaでは配列とハッシュは別々ではなく(テーブルしかない)、JavaScriptでは数値配列とハッシュ化されたオブジェクトになります。まあ、これはより明白な違いの 1 つです。

しかし、変数のスコープ、不変性、またはこのようなものに違いがあるのでしょうか?

どのように解決するのですか?

さらにいくつかの違いがあります。

  • ルア をネイティブにサポートしています。 コルーチン .
    • アップデイト : JSはジェネレータの中にyieldキーワードを含むようになり、コルーチンをサポートするようになりました。
  • ルア は変換されません は、どの比較演算子でも型間で変換しません。JSでは ===!== はジャグリングを打たないでください。
  • ルア には指数演算子 ( ^ ); JS はしません。 JS は三項条件演算子など、さまざまな演算子を使います ( ?:and/or )、そして5.3以降ではビット演算子( & , | などと比較して メタメソッド ).
    • アップデイト : JSに指数演算子が追加されました。 ** .
  • JS は、インクリメント/デクリメント、型演算子( typeofinstanceof ) 、追加の代入演算子、追加の比較演算子。
  • JS では == , === , !=!== 演算子の優先順位は > , >= , < , <= . Luaでは、すべての比較演算子は と同じ優先順位です。 .
  • ルア サポート テールコール .
  • ルア サポート 変数のリストへの代入 . ではまだ標準的ではありませんが ジャバスクリプト の標準ではありませんが、Mozilla の JS エンジン (および Opera もある程度) は、JS 1.7 (Firefox 2 の一部として利用可能) から " という名前で同様の機能をサポートしています。 構造化代入 という名前でサポートされています。JS におけるデストラクチャリングは、代入以外の文脈でも使用できるため、より一般的なものであり、たとえば 関数定義 & 呼び出し ループ初期化子 . デストラクチャーの割り当て は、しばらく前から ECMAScript (Javascript の背後にある言語標準) に追加することが提案されています。
    • アップデイト : デストラクチャリング(とデストラクチャリングアサインメント)は現在ECMAScriptの仕様の一部であり、すでに多くのエンジンで実装されています。
  • ルア であれば オーバーロード演算子 .
  • ルア で、環境を操作することができます。 getfenvsetfenv をLua 5.1では _ENV Lua 5.2 5.3 .
  • JS では、すべての関数が可変長です。また Lua では、関数は として明示的に宣言する必要があります。 .
  • Foreach JS は、オブジェクトのプロパティをループします。 前方一致 ルア (キーワード for ) はイテレータをループし、より一般的です。
    • アップデイト : JSは イテラブル のような、期待される通常のデータ構造に組み込まれているものもあります。 Array . これらは for...of の構文でループさせることができます。通常のObjectsについては、独自のイテレータ関数を実装することができます。これにより、Luaにかなり近づきました。
  • JSにはグローバルスコープとファンクションスコープがあります。 Lua には グローバルスコープとブロックスコープ . 制御構造 (例えば if , for , while ) は、新しい ブロック .

    • スコープルールの違いにより、クロージャによる外部変数の参照(Lua用語では"upvalues")が、Luaと ジャバスクリプト . これは、最もよく経験するのは のクロージャでよく見られます。 for ループ といった具合に、人によっては意表を突かれます。で ジャバスクリプト のボディは 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)
      
      

      結果として、別々の繰り返しで定義された関数は、参照されるループ変数ごとに異なるupvalueを持ちます。に対するNicolas Bolaの回答も参照してください。 Luaでのクロージャの実装は? と"の回答もご覧ください。 ループ変数上のクロージャの正しいセマンティクスは何ですか? "、" のジェネリックのセマンティクスは? "です。

      アップデイト : JSがブロックスコープを持つようになりました。で定義された変数が let または const はブロックスコープを尊重します。

  • の整数リテラルは JS は8進数で指定できます。
  • JS は明示的に Unicode をサポートしており、内部で文字列をエンコードする際には UTF-16 でエンコードされています (つまり、バイトのペアのシーケンスです)。様々な組み込みの JavaScript 関数が Unicode データを使用します。 "pâté".toUpperCase() ( "PÂTÉ" ). Lua 5.3 には、文字列リテラルの Unicode コードポイントエスケープシーケンス (JavaScript コードポイントエスケープシーケンスと同じ構文) と、組み込みの utf8 ライブラリの基本的なサポートがあります。 UTF-8 エンコーディング (の基本的なサポート(コードポイントのUTF-8へのエンコード、UTF-8のコードポイントへのデコード、文字列内のコードポイント数の取得、コードポイントの反復処理など)を提供するライブラリです。Luaの文字列は、個々のバイトの並びであり、任意のエンコーディングのテキストや、任意のバイナリデータを格納することができます。Luaには、Unicodeデータを使用する組み込み関数はありません。 string.upper の動作は、Cロケールに依存します。
  • Lua では not , or , and の代わりにキーワードを使用します。 JS 's ! , || , && .
  • ルア 用途 ~= を使うのに対して JS !== . 例えば if foo ~= 20 then ... end .
  • Lua 5.3 以降では ~ でバイナリビット単位のXORを行うのに対し JS では ^ .
  • ルア の場合、あらゆるタイプの値(ただし nilNaN ) を使ってテーブルのインデックスを作ることができます。で JavaScript では、文字列でないすべての型(Symbolを除く)は、オブジェクトのインデックスを付けるために使われる前に文字列に変換されます。例えば、以下のコードを評価した後では obj[1] になります。 "string one" となりますが、JavaScriptでは "number one" はLuaで obj = {}; obj[1] = "number one"; obj["1"] = "string one"; .
  • JS では、代入は式として扱われますが Lua ではそうではありません。従って、JSでは、代入は if , while そして do while という文がありますが、Luaでは if , while そして repeat until ステートメントを使用します。例えば if (x = 'a') {} は有効なJSですが if x = 'a' do end は無効なLuaです。
  • Lua は、ブロックスコープされた関数変数、フィールドである関数、メソッド ( local function() end , function t.fieldname() end , function t:methodname() end ). JS はこれらを等号で宣言しています ( let funcname = function optionalFuncname() {} , objectname.fieldname = function () {} ).