В чем разница между оператором let block и эквивалентом with? - PullRequest
18 голосов
/ 26 июня 2011

OBSOLETE

Блочная версия оператора let была удалена из ES6 до его финализации и была удалена из браузеров, которые ее поддерживали. Этот вопрос сейчас представляет только исторический интерес.

Есть ли разница между использованием оператора ECMAScript 6 let block и использованием оператора with с эквивалентным литералом объекта?

используя let оператор

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

используя with оператор

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"
}

Ответы [ 3 ]

8 голосов
/ 04 июля 2011

Вы можете использовать операторы with и let для достижения одной и той же цели, но я вижу здесь два существенных различия.В конце концов, оператор let является новой редакцией оператора with с устранением недостатков последнего.

Производительность : В случае оператора with выдобавить дополнительный объект JavaScript в цепочку областей действия.Это не маленькая цена, вы должны помнить, что объекты имеют потенциально длинную цепочку прототипов, и поэтому, чтобы найти переменную, движок JavaScript сначала должен найти объект и все его прототипы.С другой стороны, для оператора let движку нужно искать не более одного дополнительного объекта.Оператор 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);
}

Если вы посмотрите на код выше, что такое x и что такое y?Являются ли они функциональными переменными или свойствами объекта foo?Вы не можете сказать это, не зная, что такое foo - и это может отличаться для разных вызовов одной и той же функции.Что является основной причиной, по которой оператор with устарел.Хотя вы можете использовать его так же, как в своем вопросе (и это хорошо), он также допускает очень сомнительные и нечитаемые конструкции кода.let утверждение не делает - иногда гибкость иногда является преимуществом.

7 голосов
/ 29 июня 2011

Лучшее, что я могу придумать, это то, что with также будет пропускать любое свойство прототипа Object:

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

Маловероятно, что это будет проблемой на практике, но все же есть потенциальная ошибка.

Я также подозреваю, что with немного медленнее, чем лексические, так как он добавляет другое пространство имен, которое нужно искать.

Честно говоря, я бы просто избегал обеих конструкций; Неявный доступ к свойствам в стиле with не устраивает меня, и если мне действительно нужна такая ограниченная область видимости, то голый блок с выражениями let внутри читается менее неловко, чем блок let.

1 голос
/ 09 мая 2014

Вот различные правила определения области действия для каждого утверждения.

с:

оператор with делает доступ к именованным ссылкам неэффективным, поскольку области для такого доступа не могут быть вычислены до времени выполнения

пусть:

Область переменных, определенных с помощью let, - это сам блок let, а также любые внутренние блоки, содержащиеся в нем, если только эти блоки не определяют переменные с одинаковыми именами.

Оператор let является нестандартным, а оператор with недоступен в строгом режиме.

Ссылки

...