gán nhiều biến cho cùng một giá trị trong Javascript


177

Tôi đã khởi tạo một số biến trong phạm vi toàn cầu trong tệp JavaScript:

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

Tôi cần đặt tất cả các biến này thành false, đây là mã tôi hiện có:

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

Có cách nào để tôi có thể đặt tất cả các biến này thành cùng một giá trị trong một dòng mã không, hoặc là mã tôi hiện có cách tốt nhất để làm điều này


8
Tất cả người đọc: vui lòng xem câu trả lời thứ hai bên dưới trước khi bạn quyết định triển khai câu trả lời hàng đầu vào mã của mình. Sự thanh bình.
Govind Rai

Đừng cố gắng làm điều này, bởi vì trong bộ nhớ sẽ chỉ có một biến và các biến khác sẽ là bản sao hoặc tham chiếu cho biến đó, sau đó nếu bạn thay đổi giá trị từ tất cả sẽ bị ảnh hưởng
Lucas Matos

@LucasMatos Không dành cho người nguyên thủy.
Dave Newton

Câu trả lời:


290

Không có gì ngăn cản bạn làm

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

Kiểm tra ví dụ này

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


13
Bạn có thể muốn nhận xét cách hành vi sẽ khác các loại nguyên thủy và kiểu tham chiếu khi gán giá trị theo cách bạn đề xuất.
Steven Wexler

26
Vâng, nếu làm điều này với một đối tượng, tất cả các biến sẽ là bí danh của đối tượng. IE function MyObj(){this.x=1} var a,b; a = b = new MyObj(); ++a.xcũng sẽ tăng b.xtài sản.
AlexMorley-Finch

27
Vấn đề phạm vi! stackoverflow.com/questions/1758576/
trộm

4
Tôi sẽ nói không sử dụng phương pháp này nếu bạn không phân bổ toàn bộ các biến ở bên trái của bài tập
công dân

2
Như @doublejosh đã nói, có những vấn đề phạm vi mà bạn không giải quyết được.
kstratis

90

Không có gì ngăn cản bạn làm những điều trên, nhưng giữ vững!

Có một số vấn đề. Bài tập trong Javascript là từ phải sang trái để khi bạn viết:

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

nó có hiệu quả dịch sang:

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

có hiệu quả dịch sang:

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

Vô tình, bạn vừa tạo 5 biến toàn cục - điều mà tôi khá chắc chắn là bạn không muốn làm.

Lưu ý: Ví dụ trên của tôi giả sử bạn đang chạy mã của mình trong trình duyệt window. Nếu bạn ở trong một môi trường khác, các biến này sẽ gắn với bất kỳ bối cảnh toàn cầu nào xảy ra với môi trường đó (ví dụ, trong Node.js, nó sẽ gắn với globalbối cảnh toàn cầu cho môi trường đó).

Bây giờ trước tiên bạn có thể khai báo tất cả các biến của mình và sau đó gán chúng cho cùng một giá trị và bạn có thể tránh được vấn đề.

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

Tóm lại, cả hai cách đều hoạt động tốt, nhưng cách đầu tiên có khả năng giới thiệu một số lỗi nguy hiểm trong mã của bạn. Đừng phạm tội khi xả rác không gian tên toàn cầu bằng các biến cục bộ nếu không thực sự cần thiết.


Sidenote: Như đã chỉ ra trong các bình luận (và điều này không chỉ trong trường hợp của câu hỏi này), nếu giá trị được sao chép trong câu hỏi không phải là giá trị nguyên thủy mà thay vào đó là một đối tượng, bạn nên biết về sao chép theo giá trị so với sao chép bằng tham chiếu. Bất cứ khi nào gán đối tượng, tham chiếu đến đối tượng được sao chép thay vì đối tượng thực tế. Tất cả các biến vẫn sẽ trỏ đến cùng một đối tượng, vì vậy mọi thay đổi trong một biến sẽ được phản ánh trong các biến khác và sẽ khiến bạn đau đầu nếu ý định của bạn là sao chép các giá trị đối tượng chứ không phải tham chiếu.


2
Điều gì nếu chúng ta làm điều này với cùng?
P-RAD

Bên cạnh việc moveUptrở thành phạm vi khối, nó sẽ không có sự khác biệt. 5 biến toàn cầu vẫn sẽ được khai báo.
Govind Rai

1
@GovindRai var a, b, c; a = b = c = 10;rất khác var a = b = c = 10;. Vì vậy, câu trả lời được chấp nhận là chính xác. Bạn đang giải quyết một vấn đề không liên quan đến câu trả lời được chấp nhận.
Elis Byberi

1
@ElisByberi Cảm ơn bình luận của bạn. Bạn không sai. Mục tiêu của câu trả lời của tôi là giải quyết câu đầu tiên trong câu trả lời được chấp nhận. Tôi đã cung cấp rõ ràng hơn trong câu trả lời của tôi liên quan đến điều đó.
Govind Rai

1
@ P-RAD Chỉ có biến đầu tiên được khai báo sử dụng let sẽ tồn tại trong phạm vi kèm theo.
Uday Hiwarale

9

Có một tùy chọn khác không giới thiệu gotchas toàn cầu khi cố gắng khởi tạo nhiều biến cho cùng một giá trị. Có hay không thích đường dài hơn là một cuộc gọi phán xét. Nó có thể sẽ chậm hơn và có thể hoặc không thể đọc được nhiều hơn. Trong trường hợp cụ thể của bạn, tôi nghĩ rằng con đường dài có lẽ dễ đọc và dễ bảo trì hơn cũng như nhanh hơn.

Cách khác sử dụng phân công hủy cấu trúc .

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, '  '));

Điều này cho phép bạn khởi tạo một bộ var , lethoặc constbiến với giá trị tương tự trên một dòng duy nhất tất cả với phạm vi dự kiến tương tự.

Người giới thiệu:


1
Hãy coi chừng, tuy nhiên. Nếu gán đối tượng, hàm hoặc mảng cho nhiều biến bằng phương thức này, mỗi biến sẽ là bí danh cho sameđối tượng. Sửa đổi một cái sẽ ảnh hưởng đến những cái khác ...
Doug Coburn

-6

Đặt biến trong một mảng và Sử dụng Vòng lặp để gán cùng một giá trị cho nhiều biến.

  myArray[moveUP, moveDown, moveLeft];

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

        myArray[i] = true;

    }

3
Điều này rất sai. Câu lệnh đầu tiên không có ý nghĩa cú pháp và vòng lặp for chỉ gán các giá trị cho các chỉ mục myArray.
không xác định
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.