2010-08-02 27 views
24

Không phải là mới đối với JS hoặc cú pháp của nó, nhưng đôi khi, ngữ nghĩa của ngôn ngữ đã khiến tôi bối rối. Tại nơi làm việc ngày hôm nay, một đồng nghiệp nói này:Trong JavaScript, được gán chuỗi được không?

var a = b = []; 

là không giống như

var a = [], b = []; 

hoặc

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

kể từ khi phiên bản đầu tiên thực sự gán tham chiếu đến một mảng trống để một và B. Tôi không thể chấp nhận điều này là đúng, nhưng tôi không chắc chắn. Tất cả các bạn nghĩ gì?

+3

Xem http://stackoverflow.com/questions/1758576/multiple-left-hand-assignment-with-javascript/1758912 # 1758912 –

+0

Cảm ơn bạn, Crescent Fresh - Tôi không hoàn toàn thấy câu hỏi đó vì tôi đang tìm kiếm "chuỗi phân công". – JamieJag

Trả lời

32

Vâng, họ không giống nhau. var a = b = [] tương đương với

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

Không chỉ làm cả hai ab được gán giá trị như nhau (một tham chiếu đến các mảng sản phẩm nào giống nhau), b không tuyên bố gì cả. Trong strict mode trong ECMAScript 5 trở lên, điều này sẽ ném một số ReferenceError; nếu không, trừ khi đã có một biến số b trong phạm vi, b được tạo âm thầm dưới dạng thuộc tính của đối tượng chung và hoạt động tương tự như biến toàn cục, bất kể mã ở đâu, ngay cả bên trong một hàm. Điều đó không tốt.

Bạn có thể thấy điều này khá dễ dàng:

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

window.console.log(b); // Shows [] 
+1

Tôi không thấy ngay lập tức về b là biến toàn cục, cảm ơn! – JamieJag

+4

+1 Một lý do khác để tránh việc gán cho một tham chiếu không thể giải quyết được là trên ES5, dưới chế độ nghiêm ngặt, một 'tham chiếu' sẽ được ném ra. – CMS

4

Đồng nghiệp của bạn là đúng. Câu lệnh đầu tiên tạo một mảng mới, trống. Sau đó, tham chiếu đến mảng này được gán cho b. Sau đó, cùng một tham chiếu (là kết quả của biểu thức gán) được gán cho a. Vì vậy, a và b tham chiếu đến cùng một mảng.

Trong tất cả các trường hợp khác, bạn tạo hai mảng riêng lẻ.

Nhân tiện: Hành vi này khá phổ biến và giống nhau trong tất cả các ngôn ngữ lập trình dựa trên C. Vì vậy, đây không phải là JavaScript cụ thể.

+0

Cảm ơn bạn đã trả lời, Tobias, và cũng chỉ ra sự phổ biến trong tất cả các ngôn ngữ dựa trên C. – JamieJag

+0

Điều này có thể được kiểm tra với các mảng trong JS: '[" dog "] === [" dog "];' trả về false, nhưng 'var a = b = [" dog "]; a === b; 'trả về true. – b00t

9

đồng nghiệp của bạn là đúng:

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

nhưng:

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

Với ví dụ đầu tiên b là một tham chiếu đến a, và b trở thành một biến toàn cầu, truy cập từ bất cứ nơi nào (và nó thay thế bất kỳ b biến mà có thể đã tồn tại trong phạm vi toàn cầu).

1

Để thực hiện việc này, bạn cần phải chia tờ khai var từ việc chỉ định chuỗi (xem: http://davidshariff.com/blog/chaining-variable-assignments-in-javascript-words-of-caution/).

Ví dụ:

var one = 1, two = 2; 

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

Nhưng nếu bạn làm như bạn mô tả (var one = two = 3; trong ví dụ này) two rò rỉ vào không gian toàn cầu, trong khi one được khai báo trong phạm vi địa phương.

0

Để bổ sung cho các câu trả lời đã cung cấp.bài tập ref khác với nhiệm vụ giá trị

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] 

Bây giờ chúng tôi đã giải quyết 2 câu hỏi, đó là cách thực hành "mã đẹp" (không hoạt động). Trong thực tế, JSHint has deprecated all their "pretty code rules"

Đó được nói, tôi thường sử dụng sau 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 
Các vấn đề liên quan