19

廃止

letステートメントのブロックバージョンは、ファイナライズされる前にES6から削除され、それをサポートするブラウザーから削除されました。この質問は現在、歴史的な関心事にすぎません。

ECMAScript 6letブロックステートメントを使用するwithことと、同等のオブジェクトリテラルを持つステートメントを使用することの間に違いはありますか?

usingletステートメント

var x = 10;
let (x = x * 10,
     y = x + 5) {
    console.log("x is " + x + ", y is " + y);
}

usingwithステートメント

var x = 10;
with ({x: x * 10,
       y: x + 5}) {
    console.log("x is " + x + ", y is " + y);
    // writes "x is 100, y is 15"
}
4

3 に答える 3

8

withとステートメントの両方を使用letして同じ目標を達成できますが、ここでは2つの重要な違いがあります。結局、この声明は、後者の欠点を取り除いた声明letの新しい改訂版です。with

パフォーマンスwithステートメントの場合、スコープチェーンにJavaScriptオブジェクトを追加します。これは少額の費用ではありません。オブジェクトには潜在的に長いプロトタイプチェーンがあることを覚えておく必要があります。そのため、変数を検索するには、JavaScriptエンジンが最初にオブジェクトとそのすべてのプロトタイプを検索する必要があります。一方、letステートメントの場合、エンジンは最大で1つの追加オブジェクトを検索するだけで済みます。letステートメントで宣言されたすべての変数はletコンパイル時に既知であり、JavaScriptエンジンは、たとえば基本的に次のように例を処理することでコードを簡単に最適化できるため、ステートメントは実際にオーバーヘッドなしで実装できます。

var x = 10;
var let1x = x * 10;
var let1y = x + 5;
{
    console.log("x is " + let1x + ", y is " + let1y);
}

コードの可読性:すでに前述したように、letステートメントは常にコンパイル時にすべての宣言を表示します。これにより、次のようなコードが防止されます。

with (foo)
{
    console.log("x is " + x + ", y is " + y);
}

上記のコードを見ると、何がxyですか?それらはオブジェクトの関数変数またはプロパティfooですか?何であるかを知らずにそれを伝えることはできませんfoo-そしてそれは同じ関数の異なる呼び出しのために異なるかもしれません。withこれが、ステートメントが非推奨になった主な理由です。質問で行った方法で使用できますが(それで問題ありません)、非常に疑わしくて読めないコード構造も使用できます。このlet声明はそうではありません-柔軟性が低いことが有利な場合があります。

于 2011-07-04T13:07:55.920 に答える
7

私が思いつくことができる最善のことは、プロトタイプwithのプロパティもリークすることです。Object

with ({x: 10}) {
    hasOwnProperty = 3;
    console.log(hasOwnProperty);  // 3
}
console.log(hasOwnProperty);  // [native code]; this is window.hasOwnProperty

実際には問題になる可能性は低いですが、それでも潜在的な落とし穴です。

またwith、検索する必要のある別の名前空間が追加されるため、字句よりも少し遅いと思います。

正直なところ、私は両方の構成を避けたいと思います。with-スタイルの暗黙的なプロパティアクセスは私にはうまくいきません。そのような厳密なスコープが本当に必要な場合は、let内部に式を含む裸のブロックは、ブロックよりも扱いにくいものではありませんlet

于 2011-06-29T00:55:43.063 に答える
1

各ステートメントの異なるスコープ規則は次のとおりです。

と:

withステートメントを使用すると、名前付き参照へのアクセスが非効率になります。これは、そのようなアクセスのスコープは実行時まで計算できないためです。

させて:

letを使用して定義された変数のスコープは、letブロック自体と、その中に含まれる内部ブロックです。ただし、これらのブロックが同じ名前で変数を定義している場合を除きます。

letステートメントは非標準ですが、ステートメントwithは厳密モードでは使用できません。

参考文献

于 2014-05-08T20:23:08.257 に答える