2016-04-09 22 views
58

Dòng dưới đây làm gì?Điều gì sẽ xảy ra nếu chúng tôi đặt giá trị không xác định?

undefined = 'A value'; 

Nếu nó không thay đổi giá trị undefined thì điều gì xảy ra sau hậu trường?

+29

thực tế là nó không ném ra một lỗi là đáng lo ngại – JCOC611

+0

chỉ thử nó trong giao diện điều khiển và thậm chí không nhận được một lỗi, về cơ bản không có gì xảy ra ở tất cả https://gyazo.com/6703d9f7768e272c1aad7d3750b08ef1 – vahanpwns

+0

@AshishMishra không đúng sự thật. Nó chỉ là một tài sản của bối cảnh toàn cầu. – Pointy

Trả lời

53

undefined is a property of the global object, i.e. it is a variable in global scope. The initial value of undefined is the primitive value undefined .

Xem https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Vì vậy, nó chỉ là một biến, không có gì đặc biệt về nó. Bây giờ, để trả lời câu hỏi của bạn:

  1. undefined = 'A value'; cố gắng gán một chuỗi 'A value' vào biến toàn cầu undefined
  2. Trong trình duyệt cũ hơn những thay đổi giá trị, ví dụ: undefined === 'A value'; // true. Trong các trình duyệt mới hơn theo chế độ nghiêm ngặt, thao tác sẽ dẫn đến lỗi.

Bạn có thể kiểm tra như sau trong trình duyệt giao diện điều khiển (Tôi đang sử dụng một trình duyệt hiện đại ở đây - Google Chrome):

undefined = true; 
console.log(undefined); // undefined 
// in older browsers like the older Internet Explorer it would have logged true 

Giá trị của undefined không thay đổi trong ví dụ trên. Điều này là do (tôi nhấn mạnh):

In modern browsers (JavaScript 1.8.5/Firefox 4+), undefined is a non-configurable, non-writable property per the ECMAScript 5 specification.

Dưới chế độ nghiêm ngặt:

'use strict'; 
undefined = true; // VM358:2 Uncaught TypeError: Cannot assign to read only property 'undefined' of object 
+2

Còn về các trình duyệt mới hơn trong chế độ "không nghiêm ngặt" thì sao? nó không hiển thị bất kỳ lỗi nào. Nó có làm gì không. cuz nó không thay đổi giá trị –

+1

@Cgraphics Trong trình duyệt moder dưới chế độ không nghiêm ngặt, không có gì xảy ra. Giá trị không thể được ghi đè và không có lỗi ... nhưng, điều đó có thể thay đổi trong tương lai. – Oleg

+0

Đây là lý do tại sao đôi khi bạn sẽ thấy toán tử 'void' được sử dụng - nó đánh giá đối số của nó và sau đó trả về' undefined' và bởi vì nó là toán tử nên không thể gán giá trị. Vì vậy bạn luôn có thể nhận được 'undefined' với biểu thức' void 0' hoặc 'void (0)' (toán tử không yêu cầu parens xung quanh đối số). –

3

Tôi đã thực hiện một chút POC có và không có strict mode.

Hiệu quả là, nếu bạn không sử dụng strict mode mọi thứ đều ổn. Nếu bạn đang sử dụng strict mode bạn sẽ có một tốt đẹp:

TypeError: Cannot assign to read only property 'undefined'

Bây giờ chúng ta hãy đến POC:

"use strict" 
var c; 

if (c === undefined) { 
    console.log("nothing happened") 
} 

undefined = "goofy" 

c = "goofy" 

if (c === undefined) { 
    console.log("c is 'goofy' and it's equal to undefined.. gosh.. we broke js") 
} 

Bây giờ, như tôi đã nói, với chế độ nghiêm ngặt bạn có được một TypeError trong khi loại bỏ các "use strict" tập lệnh hoạt động tốt và đầu ra chỉ đơn giản là nothing happened.

tôi đã tìm thấy this Q/A mà có thể hữu ích nếu bạn muốn biết thêm

LƯU Ý: Tôi đã kiểm tra mã này sử dụng Node.js.

+0

Tại sao lại là node.js? Tôi nghĩ nó dành cho phía máy chủ –

+2

@Cgraphics node.js sử dụng V8 - cùng một công cụ JavaScript như Google Chrome, vì vậy về cơ bản nó giống như các quy tắc, nhưng các API khác nhau (các trình duyệt có 'window',' querySelector', vv, nút có ' global', 'fs.write', v.v.). – Oleg

+1

Vì Nút.js nó xây dựng trên V8 (Động cơ Google Chrome) sử dụng ES6 nó có vẻ là cách nhanh nhất để tạo POC. :) – FredMaggiowski

24

Không giống như những thứ như true, 123 hoặc null, undefined không phải là literal. Điều đó có nghĩa là sử dụng undefinedidentifier không phải là cách dễ dàng để có được số undefined value. Thay vào đó, có thể sử dụng void operator, ví dụ: void 0.

Theo mặc định, undefined đã xác định thuộc tính của global object, tức là biến toàn cục.Trước khi ECMAScript 5, tài sản đó là ghi, vì vậy

undefined = "A value"; 

thay thế giá trị của window.undefined, giả sử nó không được che phủ bởi một biến địa phương. Sau đó, nếu bạn đã sử dụng "A value" === undefined, bạn sẽ nhận được true. Và void 0 === undefined sẽ sản xuất false.

ECMAScript 5 đã thay đổi hành vi này và giờ thuộc tính không thể ghi cũng như không thể định cấu hình được. Do đó, các bài tập cho undefined sẽ bị bỏ qua ở chế độ không nghiêm ngặt và sẽ ném ngoại lệ là chế độ nghiêm ngặt. Dưới mui xe,

  1. undefined = "A value"; là một Simple Assignment
  2. Đó sử dụng PutValue để đưa giá trị "A value" trong một tham chiếu với cơ sở đối tượng toàn cầu, tham chiếu tên "undefined", và cờ nghiêm ngặt nếu việc chuyển nhượng được thực hiện trong chế độ nghiêm ngặt.
  3. Gọi phương thức nội bộ là đối tượng toàn cầu [[Put]], chuyển "undefined" làm tên thuộc tính, "A value" làm giá trị và cờ nghiêm ngặt làm cờ ném.
  4. Gọi phương thức nội bộ là đối tượng toàn cầu [[DefineOwnProperty]], đi qua "undefined", trình mô tả thuộc tính {[[Value]]: "A value"} và cờ ném làm đối số.
  5. Nó từ chối, có nghĩa là, ném ngoại lệ TypeError nếu cờ ném là đúng, nếu không trả về false.

Tuy nhiên, bạn vẫn có thể khai báo địa phương undefined biến:

(function() { 
    var undefined = "A value"; 
    alert(undefined); // "A value"; 
})(); 
+3

"Tuy nhiên, bạn vẫn có thể khai báo các biến không xác định cục bộ:" - Điểm tốt! –

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