2009-11-18 29 views
140
var var1 = 1, 
    var2 = 1, 
    var3 = 1; 

này tương đương với điều này:Nhiều nhiệm vụ trái với JavaScript

var var1 = var2 = var3 = 1; 

Tôi khá chắc chắn đây là thứ tự các biến được định nghĩa: var3, var2, var1, đó sẽ là tương đương này:

var var3 = 1, var2 = var3, var1 = var2; 

Có cách nào để xác nhận điều này trong JavaScript không? Sử dụng một số hồ sơ có thể?

+3

** GIAO NHẬN XÁC NHẬN CHUYỂN QUYỀN ** [ưu tiên toán tử javascript] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Opera tor_Precedence # Associativity) – neaumusic

Trả lời

324

Trên thực tế,

var var1 = 1, var2 = 1, var3 = 1; 

không tương đương với:

var var1 = var2 = var3 = 1; 

Sự khác biệt là trong Phạm vi:

function good() { 
 
    var var1 = 1, var2 = 1, var3 = 1; 
 
} 
 

 
function bad() { 
 
    var var1 = var2 = var3 = 1; 
 
} 
 

 
good(); 
 
console.log(window.var2); // undefined 
 

 
bad(); 
 
console.log(window.var2); // 1. Aggh!

Thực tế điều này cho thấy rằng nhiệm vụ là đúng liên kết.Ví dụ bad tương đương với:

var var1 = (window.var2 = (window.var3 = 1)); 
+33

Dang, đó là bất ngờ. Cảm ơn bạn đã tip, tôi sẽ xem ra cho rằng .. –

+0

Tôi không hiểu ... tại sao các biến trong xấu() được bên ngoài phạm vi chức năng? Và không nên họ được thu thập rác khi chức năng được hoàn thành? – SkinnyG33k

+10

@ SkinnyG33k bởi vì nó là phải sang trái, do đó, nó sẽ phân tích quyền nhất trước khi bên trái nhất.Vì vậy 'var var1 = var2' xảy ra sau 'var3 = 1' và sau' var2 = var3', giống như 'var3 = 1; var2 = var3; var var1 = var2' – gcb

4

Hãy thử điều này:

var var1=42; 
var var2; 

alert(var2 = var1); //show result of assignment expression is assigned value 
alert(var2); // show assignment did occur. 

Note đĩa đơn '=' trong cảnh báo đầu tiên. Điều này sẽ cho thấy kết quả của một biểu thức gán là giá trị được gán, và cảnh báo thứ 2 sẽ cho bạn thấy rằng nhiệm vụ đã xảy ra.

Nó sau một cách hợp lý nhiệm vụ đó phải có chuỗi từ phải sang trái. Tuy nhiên, vì điều này là tất cả nguyên tử cho javascript (không có luồng) một công cụ cụ thể có thể chọn để thực sự tối ưu hóa nó một chút khác nhau.

+1

Cảm ơn câu trả lời.Tôi nghĩ rằng tôi đang tìm kiếm một cách để sử dụng các cảnh báo trong khi vẫn duy trì cấu trúc nhiều nhiệm vụ (a = b = c), nhưng tôi không nghĩ rằng đó là có thể. –

+1

Các câu lệnh riêng lẻ giống như vậy trong javascript (và, mặc dù một số biểu thức, tất cả đều hoạt động với một câu lệnh đơn) có thể được coi là nguyên tử. Bạn sẽ phải phá vỡ nó. –

12

Bài tập trong javascript hoạt động từ phải sang trái. var var1 = var2 = var3 = 1;.

Nếu giá trị của bất kỳ biến nào trong số này là 1 sau tuyên bố này, thì về mặt logic phải bắt đầu từ bên phải, nếu không giá trị hoặc var1var2 sẽ không được xác định.

Bạn có thể nghĩ nó tương đương với var var1 = (var2 = (var3 = 1)); trong đó tập hợp dấu ngoặc đơn bên trong được đánh giá trước tiên.

+1

Cảm ơn, điều này chắc chắn sẽ giúp. Nó giúp để suy nghĩ về những gì lỗi sẽ được ném nếu nó được đánh giá khác hơn là phải sang trái (trong trường hợp này, lỗi sẽ là var1/var2 là không xác định). –

+5

Nó thực sự là một lỗi cú pháp. Bạn không thể có '(' ngay sau 'var'. Loại bỏ tập hợp bên ngoài của dấu ngoặc đơn cho phép nó biên dịch mà không có lỗi,' var var1 = (var2 = (var3 = 1)); '.Tại thời điểm tôi cảm thấy nó đã không 't minh họa cho điểm khá là tốt, nhưng tôi giả sử của nó như nhau, –

7
a = (b = 'string is truthy'); // b gets string; a gets b, which is a primitive (copy) 
a = (b = { c: 'yes' }); // they point to the same object; a === b (not a copy) 

(a && b) là viết tắt của (a ? b : a)

(a || b) là viết tắt của (a ? a : b)

(a = 0, b) là chữ viết tắt không quan tâm nếu a là truthy, ngầm return b


a = (b = 0) && "nope, but a is 0 and b is 0"; // b is falsey + order of operations 
a = (b = "b is this string") && "a gets this string"; // b is truthy + order of ops 

JavaScript Operator Precedence (Order of Operations)

Lưu ý rằng các nhà điều hành dấu phẩy thực sự là các nhà điều hành đặc quyền tối thiểu, nhưng ngoặc là những ưu tiên nhất, và họ đi tay trong tay khi xây dựng biểu thức một dòng.


Cuối cùng, bạn có thể cần 'khối' thay vì giá trị nguyên thủy được mã hóa cứng, và tôi chắc chắn bị trượt bởi vô tình truyền nhiều thông số, thay vì chạy qua hai biểu thức.

Với tôi, một đoạn là cả hàm và giá trị kết quả (cùng một 'điều').

const windowInnerHeight =() => 0.8 * window.innerHeight; // a thunk 

windowInnerHeight(); // a thunk 
0

coffee-script có thể thực hiện điều này với sự tự tin ..

for x in [ 'a', 'b', 'c' ] then "#{x}" : true 

[ { a: true }, { b: true }, { c: true } ]

+6

Điều này không thực sự trả lời câu hỏi. Vui lòng đọc lại câu hỏi. – Martin

+13

, người quan tâm đến coffeescript – neaumusic

5

var var1 = 1, var2 = 1, var3 = 1;

Trong trường hợp này, từ khóa var được áp dụng cho cả ba biến.

var var1 = 1, 
    var2 = 1, 
    var3 = 1; 

mà không phải là tương đương với điều này:

var var1 = var2 = var3 = 1;

Trong trường hợp này phía sau màn hình var từ khóa chỉ áp dụng cho var1 do cẩu biến và phần còn lại của biểu thức được đánh giá thông thường nên các biến var2, var3 đang trở nên globals

Javascript đối xử với mã này trong này đơn đặt hàng:

/* 
var 1 is local to the particular scope because of var keyword 
var2 and var3 will become globals because they've used without var keyword 
*/ 

var var1; //only variable declarations will be hoisted. 

var1= var2= var3 = 1; 
Các vấn đề liên quan