Tại sao (0 <5 <3) trả về đúng?


348

Tôi đã chơi xung quanh trong jsfiddle.net và tôi tò mò không biết tại sao điều này lại trở thành sự thật?

if(0 < 5 < 3) {
    alert("True");
}

Điều này cũng vậy:

if(0 < 5 < 2) {
    alert("True");
}

Nhưng điều này không:

if(0 < 5 < 1) {
    alert("True");
}

Là điều này bao giờ hữu ích?


12
Bạn có biết wtfjs.com ?
Harmen

1
Hà! Không tôi chưa từng thấy điều đó trước đây.
punkrockbuddyholly

Ah, niềm vui của chuyển đổi loại ngầm.
Jörg W Mittag

4
Bao giờ có ích? Có thể cho obfuscation. :-)
Icode4food

Tại sao? Ngoài ra, bất cứ điều gì cũng hữu ích nếu bạn chỉ có thể tìm thấy các trường hợp yêu cầu nó. Đúng, cái này ít được yêu cầu hơn so với nhiều cái khác, nhưng có những lúc, rất ít giữa chúng có thể, nơi nó có thể chính xác là công cụ cho công việc.
tạm

Câu trả lời:


440

Thứ tự các hoạt động gây ra (0 < 5 < 3)được diễn giải trong javascript khi ((0 < 5) < 3)sản xuất (true < 3)và true được tính là 1, khiến nó trả về true.

Đây cũng là lý do tại sao (0 < 5 < 1)trả về false, (0 < 5)trả về true, được hiểu là 1, dẫn đến (1 < 1).


158
Và bởi vì JavaScript không phải là Python. :-)
rsenna

1
Bạn đã trả lời trong khi tôi đang chỉnh sửa câu hỏi của mình để thêm if(0 < 5 < 1) == false. Bây giờ tất cả đã rõ ràng, cảm ơn :)
punkrockbuddyholly

28
Chính xác, Python là ngôn ngữ duy nhất tôi biết về điều trị cú pháp này ((0 < 5) && (5 < 3)), có lẽ có những ngôn ngữ khác nhưng tôi không biết về chúng.
Alan Geleynse

18
@Alan: Mathicala là một ví dụ khác.
Joren

2
IMHO JavaScript nên tăng TypeError khi cố gắng so sánh boolean với số, vì nó không có ý nghĩa.
Michał Perłakowski

63

Tôi đoán là bởi vì đó 0 < 5là sự thật, và true < 3được chọn 1 < 3là đúng.


7
Không có casting ở đây. Một diễn viên là một toán tử, mà lập trình viên sử dụng để kiểm tra rõ ràng một loại. Đây là chuyển đổi ngầm định từ boolean sang số nguyên.
erickson

4
@erickson, thực sự ... chúng ta có CẦN bị treo lên về ngữ nghĩa ở đây không?
CaffGeek

2
Đừng lo lắng về erickson. Tôi lạm dụng từ ngữ nghĩa quá. :)
Mateen Ulhaq

9
Trong mọi trường hợp thuật ngữ chính xác là cưỡng chế . Và vâng, erickson sai một phần với sự chắc chắn tuyệt đối của nó. Trong mọi trường hợp, một sự ép buộc là một loại diễn viên thường (nhưng đó chỉ là một quy ước) bạn sử dụng từ "diễn viên" để diễn tả các chuyển đổi loại rõ ràng. Chuyển đổi loại == Loại đúc.
Jack

1
Tất cả các cách ngụy biện ... Dù sao thì câu trả lời là 'tốt đẹp';)
Arman McHitarian

21

có lẽ bởi vì trueđược giả định là như 1vậy

0 < 5 < 3  -->  true < 3 -->  1 < 3  --> true


10

Đối với câu hỏi của bạn liệu việc giải quyết này có bao giờ hữu ích hay không: Tôi cho rằng có thể có một số trường hợp nó sẽ hữu ích (nếu mã cô đọng là thứ bạn đang theo đuổi), nhưng việc dựa vào nó sẽ (rất có thể) làm giảm nghiêm trọng sự dễ hiểu của mã của bạn.

Nó giống như sử dụng tăng / giảm trước / giảm như một phần của biểu thức lớn hơn. Bạn có thể xác định kết quả của mã này trong nháy mắt không?

int x = 5;
int result = ++x + x++ + --x;

Lưu ý: với mã này, đôi khi bạn thậm chí có thể nhận được các kết quả khác nhau tùy thuộc vào ngôn ngữ và trình biên dịch.

Đó là một ý tưởng tốt để làm cho cuộc sống dễ dàng cho chính bạn và người tiếp theo sẽ đọc mã của bạn. Rõ ràng viết ra những gì bạn thực sự muốn xảy ra thay vì dựa vào các tác dụng phụ như chuyển đổi ngầm định của booleans.


Vì tò mò, là result18?
punkrockbuddyholly

5
@MrMisterMan: Tôi không chắc chắn về Javascript, nhưng trong Java và C #, việc đánh giá được đảm bảo từ trái sang phải và kết quả thực sự là 18. Trong một số ngôn ngữ, như C và C ++, không có gì đảm bảo nó sẽ được đánh giá từ trái sang phải và bạn có thể kết thúc với các kết quả khác nhau tùy thuộc vào các tối ưu hóa được thêm vào bởi trình biên dịch của bạn.
Zach Johnson

9

Câu trả lời cho phần thứ hai của câu hỏi, "điều này có bao giờ hữu ích không?" có lẽ là không, như đã lưu ý bởi một câu trả lời trước đó, nếu đó thực sự là một sự ngớ ngẩn của ngôn ngữ (Javascript) mà đúng là 1, nhưng lập trình viên không nhìn chung 1 và đúng (và 0 và sai) như điều tương tự

Tuy nhiên, nếu bạn có một mô hình tinh thần của 1 là đúng và 0 là sai, thì nó dẫn đến tất cả các loại kỹ thuật boolean đẹp cực kỳ hữu ích, mạnh mẽ và trực tiếp. Ví dụ: bạn có thể tăng bộ đếm trực tiếp với kết quả A> 100, sẽ tăng bộ đếm nếu A lớn hơn 100. Kỹ thuật này có thể được xem như một trò chơi khăm hoặc lừa trong Java, nhưng bằng một mảng hoặc ngôn ngữ chức năng có thể là thành ngữ

Một ví dụ kinh điển trong ngôn ngữ mảng APL sẽ là đếm số lượng mục trong một mảng có giá trị lớn hơn 100:

+/A>100

Trong đó nếu A là mảng 5 mục 107 22 256 110 3 thì:

A>100

mang lại mảng boolean 5 mục:

1 0 1 1 0

và tổng hợp kết quả boolean này:

+/1 0 1 1 0

mang lại câu trả lời cuối cùng:

3

Câu hỏi này là một ví dụ hoàn hảo về việc kỹ thuật này sẽ rất hữu ích, đặc biệt nếu vấn đề được khái quát hóa để xác định xem n trong số các giá trị boolean có đúng không.

Kiểm tra xem ít nhất hai trong số ba booleans có đúng không


7

Điều đó thật dễ dàng.

(0 < 5 < 3)

Bắt đầu từ trái sang phải để nó đánh giá 0 <5 .. Có đúng không? Đúng. Vì TRUE = 1, nó đánh giá 1 <3. Vì 1 nhỏ hơn 3 nên nó đúng.

Bây giờ với điều này

 (0 < 5 < 1)

Là 0 nhỏ hơn 5? Đúng. Vì vậy, làm cho nó THẬT cũng có nghĩa là 1. Bây giờ với thực tế đó, nó ước tính thành (1 <1). Là 1 ít hơn 1? Không, do đó, nó sai. Nó phải bằng nhau.


4

nó đang đánh giá 0 <5 sẽ trả về 1 đúng khi 1 <3 đúng?

C # muốn cho phép bạn thực hiện điều này "Toán tử '<' không thể được áp dụng cho các toán hạng loại 'bool' và 'int'"


Đôi khi tôi nhớ sự nghiêm ngặt của C # trong các ngôn ngữ động.
Arman McHitarian

4

Tôi đã gặp phải điều này một lúc trước ở Obj-C và rất bối rối vì nó. Tôi đã nhận được kết quả mà tôi muốn bằng cách làm một cái gì đó như thế này:

if(0 < 5  && 5 < 3) {
alert("True");}

Tất nhiên đó là sai vì vậy bạn sẽ không nhận được thông báo "đúng" đó. Vui mừng tôi đọc điều này, bây giờ tôi biết tại sao.


4

Ngoài python, CoffeeScript là một ngôn ngữ khác hỗ trợ so sánh chuỗi, do đó 3 < x < 10sẽ được chuyển đổi thành (3 < x && x < 10)trong vanilla JS



1

Một toán hạng boolean khi được vận hành trên toán tử toán học trả về một số. để kiểm tra điều này chúng tôi làm

true + 1  which gives you 2.

Vì vậy 0 < 5, boolean trả về (true) được vận hành với toán tử toán học (<) sẽ trả về một số. Vì vậy, nó sôi đến 1 <3 mà trả vềtrue


1

bởi vì 0 nhỏ hơn 5 thì trả về giá trị true và theo mặc định true là mọi thứ bao gồm và có thể được ước tính thành 1 mà vẫn nhỏ hơn 3 mà lại trả về true


0

hãy thử kết quả của bạn dưới dạng Số ()

if(Number(0) < Number(5) < Number(3)) {
    alert("True");
}

hoặc thử điều này:

if(Number(0) < Number(5) && Number(5) < Number(3)) {
    alert("True");
}

Tôi đã googled điều này bởi vì tôi đã nhận được (3 >= 20) //returning truevà tôi đoán javascript đang cố kiểm tra 3như một boolean bởi vì tôi đã nhận được giá trị này từ elm.getAttribute();chức năng console.log();đang in ở dạng String.

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.