231

我在 JavaScript 文件的全局范围内初始化了几个变量:

var moveUp, moveDown, moveLeft, moveRight;
var mouseDown, touchDown;

我需要将所有这些变量设置为 false。这是我目前拥有的代码:

moveUp    = false;
moveDown  = false;
moveLeft  = false;
moveRight = false
mouseDown = false;
touchDown = false;

有什么方法可以在一行代码中将所有这些变量设置为相同的值,还是我目前有最好的方法来执行此操作?

4

5 回答 5

356

没有什么能阻止你做

moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

检查这个例子

var a, b, c;
a = b = c = 10;
console.log(a + b + c)

于 2013-06-07T02:32:54.707 回答
150

没有什么能阻止你做上述事情,但坚持住!

有一些陷阱。Javascript 中的赋值是从右到左的,所以当你写的时候:

var moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

它有效地转化为:

var moveUp = (moveDown = (moveLeft = (moveRight = (mouseDown = (touchDown = false)))));

这有效地转化为:

var moveUp = (window.moveDown = (window.moveLeft = (window.moveRight = (window.mouseDown = (window.touchDown = false)))));

不经意间,您刚刚创建了 5 个全局变量——我很确定您不想这样做。

注意:我上面的示例假设您在浏览器中运行代码,因此window. 如果您在不同的环境中,这些变量将附加到该环境的任何全局上下文(即,在 Node.js 中,它将附加到global该环境的全局上下文)。

现在您可以先声明所有变量,然后将它们分配给相同的值,您就可以避免这个问题。

var moveUp, moveDown, moveLeft, moveRight, mouseDown, touchDown;
moveUp = moveDown = moveLeft = moveRight = mouseDown = touchDown = false;

长话短说,两种方法都可以正常工作,但第一种方法可能会在您的代码中引入一些有害的错误。如果不是绝对必要的话,不要犯用局部变量乱扔全局命名空间的罪过。


旁注:正如评论中所指出的(这不仅仅是在这个问题的情况下),如果所复制的值不是原始值而是对象,那么您最好了解按值复制与按引用复制。每当分配对象时,都会复制对对象的引用而不是实际对象。所有变量仍将指向同一个对象,因此一个变量的任何更改都将反映在其他变量中,如果您的意图是复制对象值而不是引用,那么您会非常头疼。

于 2017-08-14T02:31:18.733 回答
16

当尝试将多个变量初始化为相同的值时,还有另一个选项不会引入全局陷阱。它是否比漫长的道路更可取是一个判断。它可能会更慢,并且可能会或可能不会更具可读性。在您的具体情况下,我认为很长的路可能更具可读性和可维护性以及更快。

一种方式利用解构赋值

let [moveUp, moveDown,
     moveLeft, moveRight,
     mouseDown, touchDown] = Array(6).fill(false);

console.log(JSON.stringify({
    moveUp, moveDown,
    moveLeft, moveRight,
    mouseDown, touchDown
}, null, '  '));

// NOTE: If you want to do this with objects, you would be safer doing this
let [obj1, obj2, obj3] = Array(3).fill(null).map(() => ({}));
console.log(JSON.stringify({
    obj1, obj2, obj3
}, null, '  '));
// So that each array element is a unique object

// Or another cool trick would be to use an infinite generator
let [a, b, c, d] = (function*() { while (true) yield {x: 0, y: 0} })();
console.log(JSON.stringify({
    a, b, c, d
}, null, '  '));

// Or generic fixed generator function
function* nTimes(n, f) {
    for(let i = 0; i < n; i++) {
        yield f();
    }
}
let [p1, p2, p3] = [...nTimes(3, () => ({ x: 0, y: 0 }))];
console.log(JSON.stringify({
    p1, p2, p3
}, null, '  '));

这允许您在具有相同预期范围的单行上将一组 、 或 变量初始化为相同的varletconst

参考:

于 2017-09-17T21:10:41.153 回答
8

您列出的原始变量可以使用解构赋值在一小段代码中声明并分配给相同的值。关键字let,constvar都可以用于这种类型的分配。

let [moveUp, moveDown, moveLeft, moveRight, mouseDown, touchDown] = Array(6).fill(false);
于 2020-07-20T02:17:42.967 回答
-13

将变量放入数组中并使用 for 循环将相同的值分配给多个变量。

  myArray[moveUP, moveDown, moveLeft];

    for(var i = 0; i < myArray.length; i++){

        myArray[i] = true;

    }
于 2018-09-05T18:39:52.253 回答