Câu lệnh if trong javascript có nhiều điều kiện kiểm tra tất cả chúng không?


100

Trong javascript, khi sử dụng câu lệnh if với nhiều điều kiện để kiểm tra, javascript có kiểm tra tất cả chúng không, hay nó sẽ bảo lãnh trước khi kiểm tra tất cả nếu nó đã sai?

Ví dụ:

 a = 1
 b = 2
 c = 1

 if (a==1 && b==1 && c==1)

Liệu javascript sẽ kiểm tra cả 3 điều kiện đó hay sau khi thấy rằng b không bằng 1 và do đó là sai, nó sẽ thoát khỏi câu lệnh?

Tôi hỏi từ quan điểm hiệu suất. Ví dụ: nếu tôi đang kiểm tra 3 bộ chọn jQuery phức tạp, tôi không muốn jQuery duyệt qua DOM 3 lần nếu rõ ràng qua lần đầu tiên nó sẽ trả về FALSE. (Trong trường hợp đó, việc lồng 3 câu lệnh if sẽ có ý nghĩa hơn).

ADDENDUM: Tò mò hơn, thuật ngữ thích hợp cho điều này là gì? Tôi nhận thấy rằng nhiều bạn sử dụng thuật ngữ 'ngắn mạch'. Ngoài ra, một số ngôn ngữ có làm được điều này và những ngôn ngữ khác thì không?


@Josh: Tôi hoàn toàn đánh giá cao ý tưởng rằng đây là tối ưu hóa vi mô. Đó là tốt để biết. Điều đó nói rằng nếu một tùy chọn tối ưu hơn một tùy chọn khác, tôi cho rằng thật tốt nếu biết và có thói quen sử dụng phương pháp đã nói. (Thêm nữa, tôi cũng thực sự tò mò về câu trả lời)
DA.

21
Nói một cách chính xác, đây không phải là một sự tối ưu hóa quá sớm. Trong các ngôn ngữ có logic ngắn mạch, điều quan trọng là phải biết một số phương thức sẽ không được thực thi trong điều kiện nào; nếu bạn đang dựa vào tác dụng phụ của chúng chẳng hạn.
Rob

5
Đây là một câu hỏi về "đánh giá ngắn mạch": stackoverflow.com/questions/1232603/...
David

@David. Cảm ơn! Đọc thú vị.
ĐA.

Câu trả lời:


151

Các &&nhà điều hành "ngắn mạch" - có nghĩa là, nếu điều kiện trái là sai sự thật, nó không bận tâm đánh giá một trong những quyền.

Tương tự, người ||vận hành đoản mạch nếu điều kiện bên trái là đúng.

CHỈNH SỬA: Mặc dù vậy, bạn không nên lo lắng về hiệu suất cho đến khi bạn đã đánh giá chuẩn và xác định rằng đó là một vấn đề. Tối ưu hóa vi mô sớm là hạn chế của khả năng bảo trì.


1
Câu trả lời xuất sắc (cả phần kỹ thuật và vấn đề quản lý). cảm ơn!
ĐA.

5
Nếu bạn muốn nó thực thi tất cả các phần của trạng thái boolean, bạn có thể sử dụng & và | cho and và or repspectively
Zoidberg

25
Điều kiện này không nhất thiết luôn luôn là về hiệu suất. Đôi khi bạn có thể thực hiện kiểm tra null và nói nếu kiểm tra null của bạn là điều kiện a và sau đó bạn cố gắng thực hiện a (b == giá trị + 1) cho lần kiểm tra thứ hai, bạn sẽ gặp lỗi nếu cả ba điều kiện nếu điều kiện được chọn.
infocyde

4
Thật vậy, đoản mạch không liên quan đến hiệu suất. Tuy nhiên, câu hỏi ban đầu được hỏi từ quan điểm hiệu suất.
Anon.

1
rất tốt. Thực hiện loại tối ưu hóa vi mô này (trong số những thứ khác) có thể có tác động lớn bên trong vòng lặp sự kiện cuộn, chẳng hạn như tính toán thị sai của nhiều phần tử hoặc thậm chí cả thanh dính. ví dụ như điều này: if (!barSticky && bar.parent().offset().top <= document.documentElement.scrollTop)điều kiện thứ hai là một phép tính tốn kém hơn, điều kiện đầu tiên chỉ là boolean. :)
antoni

13

Từ quan điểm hiệu suất, đây không phải là một tối ưu hóa vi mô.

Nếu chúng ta có 3 biến Boolean, a, b, c thì đó là một tối ưu hóa vi mô.

Nếu chúng ta gọi 3 hàm trả về biến Boolean, mỗi hàm có thể mất nhiều thời gian, và không chỉ cần biết ngắn mạch này mà theo thứ tự nào. Ví dụ:

if (takesSeconds() && takesMinutes())

tốt hơn nhiều so với

if (takesMinutes() && takesSeconds())

nếu cả hai đều có khả năng trả về false.


12

Đó là lý do tại sao bạn có thể làm trong mã javascript như

var x = x || 2;

Điều đó có nghĩa là nếu x là không xác định hoặc nói cách khác là 'false' thì giá trị mặc định là 2.


3
Điều này có thể hoạt động ngay cả khi JS không hỗ trợ đánh giá ngắn mạch.
pswg

1
Đây có phải là tương đương với một con chim ba ba không?
Mark Carpenter Jr

10

Trong trường hợp ai đó tự hỏi liệu có cách nào để buộc đánh giá tất cả các điều kiện hay không, trong một số trường hợp, các toán tử bitwise &|có thể được sử dụng

var testOr = true | alert(""); //alert pops up
var testAnd = false & alert(""); //alert pops up

Chúng nên được sử dụng thực sự cẩn thận vì toán tử bitwise là toán tử số học hoạt động trên các bit đơn của toán hạng của chúng và không phải lúc nào cũng hoạt động như phiên bản "không ngắn mạch" của &&||

Thí dụ:

-2147483648 && 1 = 1 

nhưng

-2147483648 & 1 = 0

Hy vọng nó sẽ giúp ích cho ai đó đã đến đây tìm kiếm thông tin như thế này (như tôi) và cảm ơn @Max về sự sửa chữa và ví dụ phản bác


1
Câu trả lời này là sai. & và | là toán tử bitwise, chúng KHÔNG phải là 'phiên bản không ngắn mạch của && và ||'. Toán tử bitwise là toán tử số học hoạt động trên các bit đơn của toán hạng của chúng. Ví dụ: -2147483648 && 1 = 1 nhưng -2147483648 & 1 = 0. Thông tin thêm tại đây: en.wikipedia.org/wiki/Bitwise_operation
Tối đa

1
@Max thực sự tôi không biết điều này, tôi đã sử dụng cái này (bây giờ tôi gọi là "mẹo") kể từ khi tôi học C. May mắn thay, những đầu vào như vậy sẽ không làm hỏng mã của tôi không bao giờ xuất hiện. Tôi sửa lại câu trả lời của tôi, tôi nợ bạn
ivcandela

@DJDaveMark xin lỗi, tôi không thể làm cho false && (alert(""))giải pháp của bạn hoạt động: /
ivcandela

@ivcandela Tôi cũng không thể. Nếu tôi không có trên điện thoại của mình, tôi sẽ kiểm tra nó đầu tiên; o) Thật tội nghiệp bạn không thể chỉnh sửa nhận xét. Tôi chỉ cần xóa nó và bổ sung khác phía dưới
DJDaveMark

Cách đơn giản hơn và tốt hơn để đánh giá lực lượng là để lưu các kết quả trong các biến sau đó kiểm tra chống lại các biến tức là:var a=false; var b=check(); alert(a && b);
DJDaveMark

7

Nó sẽ chỉ kiểm tra tất cả các điều kiện nếu những điều kiện đầu tiên là đúng, hãy tự kiểm tra nó:

javascript: alert (false && alert("A") && false);

3

Nó ngắn mạch - chỉ a và b sẽ được so sánh trong ví dụ của bạn.


3

Một lý do khác tại sao dừng đánh giá với 1 hoặc nhiều tham số ở bên trái.

if (response.authResponse && (response.authResponse.accessToken! = user.accessToken)) {...}

đánh giá thứ hai dựa trên đánh giá đầu tiên là true và sẽ không gây ra lỗi biên dịch nếu response.authResponse là null hoặc không xác định, v.v. vì điều kiện đầu tiên không thành công.

Các ngôn ngữ khác đã gặp vấn đề này trong những ngày đầu và tôi nghĩ rằng đó là cách tiếp cận tiêu chuẩn trong việc xây dựng trình biên dịch hiện nay.


2

Nó thoát ra sau khi thấy rằng b không bằng một.


2

Đối với bất kỳ ai trong câu hỏi này đều bối rối vì họ không nhìn thấy hành vi ngắn mạch khi sử dụng ||kết hợp với một ?toán tử như vậy:

x = 1 || true ? 2 : 3 // value of x will be 2, rather than 1 as expected

có vẻ như quy tắc ngắn mạch không hoạt động. Tại sao nó lại đánh giá số hạng thứ hai của ||(đúng? 2: 3) trong khi số hạng đầu tiên là đúng? Nó chỉ ra là một vấn đề thứ tự hoạt động vì ở trên là tương đương với

x = (1 || true) ? 2 : 3

với ||đánh giá đầu tiên và ?đánh giá thứ hai. Những gì bạn có thể muốn là:

x = 1 || (true ? 2 : 3)

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.