Подтвердить что ты не робот

В чем разница между выражением 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"
}
4b9b3361

Ответ 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 недоступен в строгом режиме.

Ссылки