2012-01-21 26 views
5

Tôi đã thấy điều này khá hài hước screencast hôm qua về một số oddities bằng các ngôn ngữ như Ruby và Javascript và anh chàng cho thấy:Tại sao Mảng + Mảng bằng chuỗi rỗng?

[] + [] -> "" // returns empty string 

không phải là rất rõ ràng ...

tôi đã quyết định đi đến số ECMAscript language specification để biết thêm thông tin. Tôi đã bắt đầu với việc thực hiện + điều hành (trang 75) mà nói:

11.6.1 Các nhà điều hành Addition (+)

Các nhà điều hành bổ sung hoặc thực hiện chuỗi nối, bổ sung số.
Sản phẩm AdditiveExpression: AdditiveExpression + MultiplicativeExpression được đánh giá như sau:
1. Hãy để lref là kết quả của việc đánh giá AdditiveExpression.
2. Hãy để khoản tiền là GetValue (lref).
3. Cho rref là kết quả của việc đánh giá MultiplicativeExpression.
4. Hãy để rval là GetValue (rref).
5. Hãy để lprim là ToPrimitive (lval).
6. Hãy để rprim là ToPrimitive (rval).
7. Nếu Type (lprim) là String hoặc Type (rprim) là String, thì
a. Trả về String là kết quả của việc ghép nối ToString (lprim) theo sau bởi ToString (rprim)
8. Trả về kết quả của việc áp dụng thao tác bổ sung vào ToNumber (lprim) và ToNumber (rprim). Xem phần Lưu ý dưới đây 11.6.3.

CHÚ Ý1 Không có gợi ý nào được cung cấp trong các cuộc gọi đến ToPrimitive trong bước 5 và 6. Tất cả đối tượng ECMAScript gốc ngoại trừ đối tượng Ngày xử lý sự vắng mặt của gợi ý như số gợi ý đã được đưa ra; Các đối tượng ngày xử lý sự vắng mặt của một gợi ý như thể chuỗi gợi ý đã được đưa ra. Các đối tượng lưu trữ có thể xử lý sự vắng mặt của một gợi ý theo một cách khác.

CHÚ Ý 2 Bước 7 khác với bước 3 của thuật toán so sánh cho toán tử quan hệ (11.8.5), bằng cách sử dụng phép toán logic hoặc thay vì logic và hoạt động.

tôi đoán là điểm 7 đã đạt được một cách nào đó thông qua đánh giá khác nhau/chuyển đổi như đã mô tả trước đây nhưng tôi không thể tìm ra những gì đang thực sự xảy ra sự ...

Ai đó có thể cung cấp một lời giải thích đơn giản cho nhiều điều này ?


tôi sẵn sàng để hiểu tất cả điều này tốt hơn một chút để cố gắng trả lời lý do tại sao:

[] + {} -> [object Object] 
{} + [] -> 0 

Trả lời

7
  1. Hãy lprim được ToPrimitive (lval).
  2. Hãy để rprim là ToPrimitive (rval).

Vì không có gợi ý được cung cấp cho ToPrimitive:

Khi [[DefaultValue]] phương pháp nội bộ của O được gọi mà không có gợi ý, sau đó nó cư xử như thể gợi ý là Number, trừ khi O là đối tượng Date (xem 15.9.6), trong trường hợp này, nó hoạt động như thể gợi ý là Chuỗi.

Vì vậy, nó giống như gọi với một chút Số:

When the [[DefaultValue]] internal method of O is called with hint Number, the following steps are taken: 
1. Let valueOf be the result of calling the [[Get]] internal method of object O with argument "valueOf". 
2. If IsCallable(valueOf) is true then, a. Let val be the result of calling the [[Call]] internal method of valueOf, with O as the this value and an empty argument list. b. If val is a primitive value, return val. 
3. Let toString be the result of calling the [[Get]] internal method of object O with argument "toString". 
4. If IsCallable(toString) is true then, a. Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list. b. If str is a primitive value, return str. 
5. Throw a TypeError exception. 

Kể từ khi giá trị trả về của [].valueOf() không phải là một nguyên thủy, nó đi đến [].toString() trả về "".

cùng này áp dụng cho các đối tượng đối tượng, trừ các .toString của một đối tượng trả về [object Object] khi .toString của một mảng trả về .join(",")


{} + []

Các {} không được coi là một đối tượng ở đây nhưng như một khối trống. Vì vậy, các mã mà chạy là:

{} 
+[]; //Same as +[] (Number([])) which is 0 

Để giải quyết sự mơ hồ và nhận được kết quả bình thường từ {} + [] sử dụng

({}) + [] hoặc ({} + [])

đang vui:

{} ! [] //false 
({}) ! [] //SyntaxError 
+0

Làm cho ý nghĩa hơn bây giờ. Các đặc điểm kỹ thuật có thể được khá mặc dù để có được vào nhưng có một số dẫn bây giờ. Cảm ơn. –

+0

@DidierGhys yep, cẩn thận với đối tượng theo nghĩa đen, javascript là rất háo hức để đối xử với họ như là khối bất cứ nơi nào nó có thể. – Esailija

+0

Tôi sẽ ghi nhớ điều đó. –

Các vấn đề liên quan