In JavaScript, is chained assignment okay?

前端 未结 6 1129
南笙
南笙 2020-12-01 08:59

Am not new to JS or its syntax, but sometimes, the semantics of the language has me stumped at times. At work today, a colleague mentioned this:

var a = b =          


        
相关标签:
6条回答
  • 2020-12-01 09:26

    Your colleague is right:

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

    but:

    var a = [], b = [];
    a.push('something');
    console.log(b);          // outputs []
    
    0 讨论(0)
  • 2020-12-01 09:31

    To accomplish this, you need to split the var declaration from the chained assignment (see: http://davidshariff.com/blog/chaining-variable-assignments-in-javascript-words-of-caution/ ).

    E.g.

    var one = 1, two = 2;
    
    one = two = 3; /* Now both equal 3 */
    

    But if you do as you described (var one = two = 3; in this example) two leaks into the global space, while one is declared in the local scope.

    0 讨论(0)
  • 2020-12-01 09:32

    With the first example b is a reference to a, and b becomes a global variable, accessible from anywhere (and it replaces any b variable that may already exist in the global scope).

    0 讨论(0)
  • 2020-12-01 09:34

    Yes, they're not the same. var a = b = [] is equivalent to

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

    Not only do both a and b get assigned the same value (a reference to the same empty array), b is not declared at all. In strict mode in ECMAScript 5 and later, this will throw a ReferenceError; otherwise, unless there is already a variable b in scope, b is silently created as a property of the global object and acts similarly to a global variable, wherever the code is, even inside a function. Which is not good.

    You can see this quite easily:

    (function() {
        var a = b = [];
    })();
    
    console.log(b); // Shows []
    
    0 讨论(0)
  • 2020-12-01 09:41

    Your colleague is right. The first statement creates a new, empty array. Then, a reference to this array is assigned to b. Then, the same reference (which is the result of the assignment expression) is assigned to a. So a and b refer to the same array.

    In all other cases, you create two individual arrays.

    By the way: This behavior is quite common and is the same in all C based programming languages. So this is not JavaScript specific.

    0 讨论(0)
  • 2020-12-01 09:49

    To complement the already provided answers. ref assignments are different from value assignments

    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]
    

    Now that we've addressed 2 two, your question also makes reference to linting, which is the practice of "pretty code" (not functional). In fact, JSHint has deprecated all their "pretty code rules"

    That been said, I usually use the following style.-

    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
    
    0 讨论(0)
提交回复
热议问题