Множество левых заданий с использованием JavaScript
var var1 = 1,
var2 = 1,
var3 = 1;
Это эквивалентно этому:
var var1 = var2 = var3 = 1;
Я уверен, что это порядок, определяющий переменные: var3, var2, var1, который был бы эквивалентен этому:
var var3 = 1, var2 = var3, var1 = var2;
Есть ли способ подтвердить это в JavaScript? Возможно, с помощью какого-то профилировщика?
Ответы
Ответ 1
На самом деле,
var var1 = 1, var2 = 1, var3 = 1;
не эквивалентен:
var var1 = var2 = var3 = 1;
Разница в области охвата:
function good() {
var var1 = 1, var2 = 1, var3 = 1;
}
function bad() {
var var1 = var2 = var3 = 1;
}
good();
console.log(window.var2); // undefined
bad();
console.log(window.var2); // 1. Aggh!
Ответ 2
Назначение в JavaScript работает справа налево. var var1 = var2 = var3 = 1;
,
Если значение какой-либо из этих переменных равно 1
после этого оператора, то логически оно должно начинаться справа, в противном случае значение или var1
и var2
будут неопределенными.
Вы можете думать об этом как о эквиваленте var var1 = (var2 = (var3 = 1));
где самый внутренний набор скобок оценивается первым.
Ответ 3
a = (b = 'string is truthy'); // b gets string; a gets b, which is a primitive (copy)
a = (b = { c: 'yes' }); // they point to the same object; a === b (not a copy)
(a && b)
логически (a? b: a)
и ведет себя как умножение (например, !!a * !!b
)
(a || b)
логически (a? a: b)
и ведет себя как сложение (например, !!a + !!b
)
(a = 0, b)
сокращенно означает, что не заботиться, если a
верно, неявно вернуть b
a = (b = 0) && "nope, but a is 0 and b is 0"; // b is falsey + order of operations
a = (b = "b is this string") && "a gets this string"; // b is truthy + order of ops
Приоритет оператора JavaScript (порядок операций)
Обратите внимание, что оператор запятой на самом деле является оператором с наименьшими привилегиями, но скобки являются наиболее привилегированными, и они идут рука об руку при построении выражений в одну строку.
В конце концов, вам могут понадобиться "thunks", а не жестко заданные значения, и для меня thunk - это и функция, и результирующее значение (одно и то же "вещь").
const windowInnerHeight = () => 0.8 * window.innerHeight; // a thunk
windowInnerHeight(); // a thunk
Ответ 4
var var1 = 1, var2 = 1, var3 = 1;
В этом случае ключевое слово var
применимо ко всем трем переменным.
var var1 = 1,
var2 = 1,
var3 = 1;
что не эквивалентно этому:
var var1 = var2 = var3 = 1;
В этом случае за экранами ключевое слово var
применимо только к var1
из-за переменной подъема и остальная часть выражения оценивается нормально, поэтому переменные var2, var3
становятся глобальными
Javascript обрабатывает этот код в следующем порядке:
/*
var 1 is local to the particular scope because of var keyword
var2 and var3 will become globals because they've used without var keyword
*/
var var1; //only variable declarations will be hoisted.
var1= var2= var3 = 1;
Ответ 5
Попробуйте следующее:
var var1=42;
var var2;
alert(var2 = var1); //show result of assignment expression is assigned value
alert(var2); // show assignment did occur.
Обратите внимание на сингл '=' в первом предупреждении. Это покажет, что результатом выражения присваивания является назначенное значение, а второе предупреждение покажет вам, что это присвоение действительно произошло.
Логически следует, что назначение должно иметь цепочку справа налево. Однако, поскольку это все атомарно для javascript (там нет потоков), конкретный движок может предпочесть фактически оптимизировать его немного по-другому.
Ответ 6
К настоящему времени ясно, что они не совпадают, но следующие строки
var var1, var2, var3
var1 = var2 = var3 = 1
А как насчет пусть назначения? Точно так же, как var, не позволяйте заданию let сбить вас с толку из-за объема блока.
let var1 = var2 = 1 // here var2 belong to the global scope
Мы могли бы сделать следующее:
let v1, v2, v3
v1 = v2 = v3 = 2
Примечание: кстати, я не рекомендую использовать несколько назначений, даже не несколько объявлений
Ответ 7
coffee-script
может выполнить это с помощью aplomb..
for x in [ 'a', 'b', 'c' ] then "#{x}" : true
[ { a: true }, { b: true }, { c: true } ]