2012-01-19 38 views
5

Nếu tôi thực hiện đoạn mã sau trong Firebug an ủi nó bằng cách nào đó in surprise!:Javascript: lạ so sánh hành vi

['surprise!', 'boring'][Number(0=="​")] 

Nhưng tại sao?

UPD

Tôi xin lỗi, con người, đó là một trò đùa! Jere là người đầu tiên chú ý! Hôm qua tôi tìm thấy một ZERO WIDTH SPACE trong một chuỗi, và có kể từ đó cám dỗ để có một số vui vẻ =)

+0

Ý bạn là 'surprize!' đúng? – Jere

+0

@micha, hãy chú ý đến '==', không phải '===' – newtover

+0

Không, con bọ lửa của anh ấy nhận ra những sai lầm và sửa chúng. – shift66

Trả lời

9

Có một ký tự thừa, không hiển thị giữa báo giá của bạn.

Nếu bạn gõ này ra, bạn sẽ nhận được 'nhàm chán' vì 0 == "" để đánh giá đúng, Số (true) evalutes để 1.

Dán hai và xem kết quả khác nhau:

0=="​" 

đầu ra sai

0=="" 

đầu ra đúng

Điều duy nhất tôi đã thay đổi là xóa ký tự giữa "".

+0

+1. Trong một khoảnh khắc, tôi nghĩ bàn điều khiển đã bị lỗi. Tốt đẹp! – cheeken

+0

Điều gì là gian lận ... – Raynos

+1

Có, Jere là đúng. Sao chép và dán dòng ở đâu đó, sau đó di chuyển bằng mũi tên trên bàn phím và bạn sẽ nhận thấy thêm một điểm dừng nữa. Nó có thể là không gian rất nhỏ – welldan97

8

0=="​"false (Bởi vì bạn có một nhân vật không được in trong chuỗi), Number(false)0 (theo page 34 of the spec), và "ngạc nhiên" là chỉ số thứ 0 của mảng.

+0

Bạn xứng đáng được bình chọn nhiều hơn bạn của tôi – Joe

4

ES5 11.9.3 The == operator

Nếu Type (x) là số lượng và loại (y) là String, trả lại kết quả của việc so sánh x == ToNumber (y).

Các MV của StringNumericLiteral ::: [trống] là 0.

Vì vậy 0=="" lợi nhuận 0 == ToNumber("") đó là 0 == 0 đó là sự thật.

Đến == quy tắc chuyển đổi 0==""true

ES5 15.7.1.1 Number (value) gọi ES5 9.3 toNumbertoNumber(true) === 1

["suprize!", "boring"][1] lợi nhuận "boring" mà rõ ràng là không chính xác.

Tại sao lại chính xác?Bởi vì

"​".charCodeAt(0) === 8203

Chuỗi chữ của bạn không phải là chuỗi rỗng. Bạn có một số zero width space trong chuỗi của mình.

Bây giờ nếu chúng ta quay trở lại ES5 11.9.3 == operator chúng ta thấy

Nếu ngữ pháp không thể giải thích String như một mở rộng của StringNumericLiteral

Có nghĩa

  • 0==""
  • 0==NaN
  • false
  • toNumber(false) === 0
  • Number(0=="") === 0
  • ["suprize!", "boring"][0] === "suprize!"
1

['surprise!', 'boring'][Number(0=="​")] sẽ trở lại 'nhàm chán' becouse mã của bạn:

Number(0=="​") //returns true 

Nhưng mã của bạn là khác nhau, bạn có một char vô hình trong văn bản của bạn, đó là lý do tại sao trả về sai.

Nếu bạn viết mã chính xác sẽ trả về đúng và kết quả sẽ là boring như mong đợi.

Nhưng nếu sao chép và dán mã của bạn, sẽ trả về false, đó là lý do tại sao bạn có một char giữa "" (bạn có thể kiểm tra sử dụng bàn phím hoặc "" .length)

do đó, mã của bạn sẽ trả về false , đó sẽ là 0 rồi trả lại 'bất ngờ!'

Bạn đang lừa dối người đàn ông: P

['surprise!', 'boring'][Number(0=="​")] 

"​".length //returns 1 ;) 

"​" != "" // OH GOD THIS IS TRUE :P 
0

tôi nhận được nhàm chán khi chạy này trong giao diện điều khiển console.log ([ '! Surpeise', 'nhàm chán'] [Số (0 == "")])