Hôm nay tôi nhận thấy rằng Chrome 49 không còn xuất ra NaN
khi bạn nhập {}+{}
vào bảng điều khiển. Thay vào đó, nó đưa ra chuỗi [object Object][object Object]
.
Tại sao lại thế này? Ngôn ngữ có thay đổi không?
Hôm nay tôi nhận thấy rằng Chrome 49 không còn xuất ra NaN
khi bạn nhập {}+{}
vào bảng điều khiển. Thay vào đó, nó đưa ra chuỗi [object Object][object Object]
.
Tại sao lại thế này? Ngôn ngữ có thay đổi không?
Câu trả lời:
Chrome devtools hiện tự động bao bọc mọi thứ bắt đầu {
và kết thúc bằng }
một cặp dấu ngoặc đơn ( xem mã ), để buộc đánh giá của nó là một biểu thức. Bằng cách đó, {}
tạo ra một đối tượng trống bây giờ. Bạn có thể thấy điều này nếu bạn quay lại lịch sử ( ↑), dòng trước đó sẽ được chứa trong đó (…)
.
Tại sao? Tôi không biết, nhưng tôi có thể đoán nó làm giảm sự nhầm lẫn cho những người mới không biết về khối chữ-đối tượng-nghĩa đen và nó cũng hữu ích hơn nếu bạn chỉ muốn đánh giá một biểu thức.
Và trên thực tế, đó là lý do, như đã thảo luận trong lỗi 499864 . Tinh khiết tiện lợi. Và bởi vì nút REPL cũng có nó ( xem mã ).
{a:1}),({b:2}
nên ném một lỗi, không tạo ra một đối tượng.
)
trong trường hợp nó trong một bình luận, ví dụ như {a:3} // :-}
vẫn có thể tạo ra một đối tượng.
Nếu bạn nhấn mũi tên lên sau khi kiểm tra điều này, bạn sẽ nhận thấy rằng thay vì {} + {}
nó hiển thị ({} + {})
, kết quả sẽ dẫn đến "[object Object][object Object]"
.
So sánh, trong Firefox, {} + {}
vẫn hiển thị NaN
, nhưng nếu bạn làm ({} + {})
thì nó cũng hiển thị "[object Object][object Object]"
.
Vì vậy, có vẻ như Chrome đang tự động thêm dấu ngoặc đơn xung quanh khi thấy hoạt động này.
{} + {}
khi không được "khử trùng" thành ({} + {})
được coi là + {}
vì {}
được phân tích cú pháp dưới dạng một khối trống.
{}
chỉ là một khối mã rỗng và được bỏ qua, để lại cho chúng ta +{}
, mà là một unary +
và một đối tượng rỗng người khởi tạo. +
sẽ ép buộc đối số của nó thành số, liên quan đến việc chuyển đổi đối tượng thành nguyên thủy (kết quả là toString
trong trường hợp này, dẫn đến "[object Object]"
), và vì vậy chúng ta nhận được +"[object Object]"
đó là NaN
vì "[object Object]"
không thể chuyển đổi thành số hợp lệ.
Thật không may, tôi đã thêm trích dẫn Clippy mình. Bảng điều khiển không cung cấp thông tin về những gì nó đã làm cho bạn.
Các quy tắc mới cực kỳ đơn giản giúp chúng tôi tránh được rắc rối khi phải gõ 2 từ khóa khó khăn này o=
hoặc 0,
trước khi dán Object Literals vào bảng điều khiển:
{
;{wat:1}),({wat:2}
Cuối cùng là một lỗi một lần nữa.
{let i=0;var increment=_=>i++}
cuối cùng được cho phép một cách chính xác, đó là một cách khá hay để thực hiện việc đóng cửa.
Tuy nhiên, sau đây không chính xác là một đối tượng, đây chỉ là một sự tiện lợi như được đề cập bởi @Bergi, nó diễn giải sai JS để giúp bạn! Thông số kỹ thuật cho biết đây là một khối có câu lệnh được dán nhãn "foo" với nghĩa đen 1 không được gán cho bất cứ điều gì.
{foo:1}
Ở trên nên giống như
if(1) {
foo: 1
}
Sau đây được coi là một khối ... bởi vì nó có một bình luận ở phía trước của nó!
//magic comment
{foo:1}
Đây là:
{foo:1}
//also magic
Đây là một đối tượng:
{foo:
//not so magic comment
1}
Đây là một lỗi
//not so magic comment
{foo:1}.foo
Đây là:
{foo:1}.foo
Điều này tốt
1..wat
undefined
đây là
['foo'][0]
Cái tiếp theo được hiểu chính xác là một đối tượng được đưa vào vị trí biểu thức với cái 0,
mà nói chung là cách chúng ta rõ ràng đảm bảo rằng chúng ta có một biểu thức thay vì một câu lệnh.
0,{foo:1}.foo
Tôi không hiểu tại sao họ bọc giá trị trong parens. JS có một số quyết định thiết kế lố bịch, nhưng cố gắng làm cho nó hoạt động tốt hơn trong tình huống này không thực sự là một lựa chọn, giao diện điều khiển cần chạy JS chính xác và chúng tôi cần phải tự tin rằng chrome không chỉ đoán rằng nó nghĩ rằng chúng tôi nghĩ thực sự có nghĩa là nó để làm một cái gì đó khác.
Nếu bạn không thích toán tử dấu phẩy, bạn có thể sử dụng phép gán
x = {foo:1}.foo
Bởi vì khi nó đứng
{} + {} + {}
"[object Object][object Object][object Object]"
;{} + {} + {}
"NaN[object Object]"
Điên rồ và kiên định Tôi có thể đối phó với ... điên và không nhất quán không cảm ơn bạn!
{foo:1}
và {foo:1}//
sản xuất điều tương tự. Trong REPL Chrome họ không. REPL đang làm nhiều hơn là chỉ đánh giá JS. Đó là xử lý các chuỗi và quyết định những thứ khác nhau.
var x = eval('{a:1}')
Trong JavaScript x hợp lệ bây giờ là 1, không phải là đối tượng trực quan hơn {a: 1}. Vâng, điều đó thật kỳ lạ, nhưng bạn không thể thay đổi ngôn ngữ vì nó làm những điều kỳ lạ. Mọi thứ ngoài chuỗi JSON đều được hiểu là JavaScript và được đánh giá. Việc nhập 0,
trước khi dán JSON không khó, thay vào đó, tôi rất vui khi có cảnh báo rằng chuỗi được hiểu là một đối tượng thay vì JavaScript để thuận tiện.
var e = {}; e.toString()
và bạn sẽ thấy ý của tôi