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

В JavaScript привязано к цепочке?

Я не новичок в JS или его синтаксисе, но иногда семантика языка иногда меня раздражает. На работе сегодня коллега упомянул об этом:

var a = b = [];

не совпадает с

var a = [], b = [];

или

var a = []; var b = [];

так как первая версия фактически присваивает ссылку на пустой массив на a и b. Я не мог признать это правдой, но я не уверен. Что вы все думаете?

4b9b3361

Ответ 1

Да, они не одинаковы. var a = b = [] эквивалентно

var a;
b = [];
a = b;

Мало того, что a и b получают одинаковое значение (ссылка на один и тот же пустой массив), b вообще не объявляется. В строгом режиме в ECMAScript 5 и более поздних версиях это вызовет ReferenceError; в противном случае, если в области видимости уже нет переменной b, b автоматически создается как свойство глобального объекта и действует аналогично глобальной переменной, где бы ни находился код, даже внутри функции. Что не хорошо.

Вы можете увидеть это довольно легко:

(function() {
    var a = b = [];
})();

console.log(b); // Shows []

Ответ 2

Ваш коллега прав:

var a = b = [];
a.push('something');
console.log(b);          // outputs ["something"]

а

var a = [], b = [];
a.push('something');
console.log(b);          // outputs []

Ответ 3

Ваш коллега прав. Первый оператор создает новый пустой массив. Затем ссылку на этот массив присваивается b. Затем той же ссылке (которая является результатом выражения присваивания) присваивается значение a. Таким образом, a и b относятся к одному и тому же массиву.

Во всех остальных случаях вы создаете два отдельных массива.

Кстати: Такое поведение довольно распространено и одно и то же во всех языках программирования на языке C. Так что это не специфичный JavaScript.

Ответ 4

В первом примере b есть ссылка на a, а b становится глобальной переменной, доступной из любого места (и она заменяет любую переменную b, которая может уже существовать в глобальной области).

Ответ 5

Для этого вам нужно разбить объявление var из привязанного назначения (см. http://davidshariff.com/blog/chaining-variable-assignments-in-javascript-words-of-caution/).

например.

var one = 1, two = 2;

one = two = 3; /* Now both equal 3 */

Но если вы сделаете так, как вы описали (var one = two = 3; в этом примере), two просачивается в глобальное пространство, а one объявляется в локальной области.

Ответ 6

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

var x = y = 3; // by value
y++; // 4
x; // 3

var a = b = []; // by ref
b.push(1); // [1];
a; // [1]
a = [];
a.push(2); // [2];
b; // [1]

Теперь, когда мы обратились к двум двум, ваш вопрос также касается линтинга, который является практикой "красивого кода" (не функционального). На самом деле, JSHint устарел во всех "правилах красивого кода"

Тем не менее, я обычно использую следующий стиль. -

var a, b, c, // first row all unassigned
    x = 1, // 1 row per assigned
    y = 2,
    list = [
       'additional',
       'indentation'
    ],
    obj = {
       A: 'A',
       B: 'B'
    };
var z = y +2; // created a new 'var' cluster since it uses a var from the previous