将多个变量分配给Javascript中的相同值


177

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

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

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

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

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


8
所有读者:在决定将最高答案纳入代码之前,请查看下面的第二个答案。和平。
Govind Rai

不要尝试这样做,因为在内存中只有一个变量,而另一个将是该变量的副本或引用,那么如果您将值更改为一个,则所有变量都会受到影响
Lucas Matos

@LucasMatos不适合基元。
戴夫牛顿

Answers:


287

没有什么可以阻止你的

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

检查这个例子

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


13
您可能想评论在按照建议的方式分配值时,行为将如何与原始类型和引用类型有所不同。
Steven Wexler 2013年

26
是的,如果对一个对象执行此操作,则所有变量将是该对象的别名。IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.x也将增加该b.x属性。
2014年


4
我要说的是,如果您不在全局范围内分配任务左侧的所有变量,请不要使用这种方法
公民conn 2015年

2
正如@doublejosh所说,存在您未解决的范围界定问题。
kstratis

88

没有什么可以阻止您执行上述操作,但请坚持!

有一些陷阱。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;

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


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


2
如果我们对let做同样的事情怎么办?
P-RAD

除了moveUp成为块状观察对象之外,这没有什么区别。仍将声明5个全局变量。
Govind Rai

@GovindRai var a, b, c; a = b = c = 10;与完全不同var a = b = c = 10;。因此,可接受的答案是正确的。您正在解决与接受的答案无关的问题。
Elis Byberi

1
@ElisByberi感谢您的评论。你没看错 我的答案是解决已接受答案中的第一句话。关于这一点,我的回答更加清楚。
Govind Rai

问题已经声明了变量已声明,但是添加此答案仍然是一个好主意。
大卫·卡兰南

9

当试图将多个变量初始化为相同的值时,还有一个不引入全局陷阱的选项。从长远来看是否可取是一个判断电话。它可能会更慢,可能会或可能不会更具可读性。在您的特定情况下,我认为长距离可能更易读,更易维护且速度更快。

其他方式使用解构赋值

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在一行中的变量相同的值都具有相同的预期范围。

参考文献:


1
但是要当心。如果使用此方法将对象,函数或数组分配给多个变量,则每个变量将是same对象的别名。修改其中一个会影响其他人……
Doug Coburn

-6

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

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }

3
这是非常错误的。第一条语句在语法上没有意义,并且for循环只是将值分配给myArray索引。
undefinederror
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.