В чем разница между выражением let block и эквивалентом с выражением?
ИСП
Блочная версия оператора let была удалена с ES6 до ее завершения, и она была удалена из браузеров, которые ее поддерживали. Этот вопрос сейчас представляет только исторический интерес.
Есть ли разница между использованием инструкции ECMAScript 6 let
и использованием оператора 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"
}
Ответы
Ответ 1
Лучшее, что я могу придумать, состоит в том, что with
также пропустит любое свойство прототипа Object
:
with ({x: 10}) {
hasOwnProperty = 3;
console.log(hasOwnProperty); // 3
}
console.log(hasOwnProperty); // [native code]; this is window.hasOwnProperty
Вряд ли будет проблемой на практике, но все же потенциальная добыча.
Я также подозреваю, что with
немного медленнее, чем лексика, поскольку он добавляет другое пространство имен, которое нужно искать.
Честно говоря, я бы просто избегал обеих конструкций; with
-листный неявный доступ к свойствам не подходит для меня, и если мне действительно нужна такая ограниченная область, пустой блок с выражением let
внутри читается менее неудобно, чем блок let
.
Ответ 2
Вы можете использовать операторы 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
не имеет особого преимущества.
Ответ 3
Ниже приведены различные правила для каждого утверждения.
с:
оператор with делает доступ к именованным ссылкам неэффективным, поскольку области для такого доступа не могут быть вычислены до времени выполнения
пусть:
Объем переменных, определенных с помощью let, - это сам блок let, а также любые внутренние блоки, содержащиеся внутри него, если только эти блоки не определяют переменные одинаковыми именами.
Оператор let
нестандартен, а оператор with
недоступен в строгом режиме.
Ссылки