Tại sao không xác định không thể ghi trong JavaScript?


59

Theo tài liệu của MDN vềundefined :

Trong các trình duyệt hiện đại (JavaScript 1.8.5 / Firefox 4+), không xác định là thuộc tính không thể cấu hình, không thể ghi theo đặc tả ECMAScript 5. Ngay cả khi đây không phải là trường hợp, tránh ghi đè nó.

Một trong những thuộc tính thuộc tính không xác định là không thể ghi.

Nhưng nếu tôi làm:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);
//string

Điều đó có nghĩa là tôi có thể ghi đè lên giá trị của undefined? Điều gì xảy ra nếu ai đó làm điều đó? JavaScript có nên cảnh báo về điều đó?


5
bạn có thể cho chúng tôi biết bạn sử dụng trình duyệt nào không? (Firefox 72.0b10 (64 bit) trên Linux hoạt động như dự định typeof test === "undefined")
jonatjano

3
@DmitryReutov typeof undefinedtrở lại "undefined"trong trường hợp bình thường.
Amy

3
@DmitryReutov Tất nhiên "undefined"là một chuỗi. Câu hỏi không phải là hỏi những gì typeof (typeof undefined)đánh giá. Đó là hỏi những gì typeof undefinedđánh giá. Nó trở lại "undefined", không phải"string"
Amy

2
@DmitryReutov typeof ______là một biểu thức ước lượng thành một chuỗi chứa kiểu của ______. Bạn đang hiểu nhầm câu hỏi.
Amy

3
@ Tôi biết, nhưng Edge trả về "chuỗi" và Chrome "không xác định"
Alon Eitan

Câu trả lời:


50

Một bình luận bị loại bỏ bởi Amy đưa ra giải pháp. Bạn đang tạo một biến có tên undefinedvà nó không hoạt động nếu bạn thực hiện các đoạn mã của mình trong phạm vi toàn cầu:

var undefined = 'hello';
var test = undefined;
console.log(typeof test);

Nhưng nó hoạt động hiệu quả nếu bạn thực hiện nó trong phạm vi cục bộ nơi không xác định không đề cập đến biến toàn cục nữa:

(()=>{
  var undefined = 'hello';
  var test = undefined;
  console.log(typeof test);
})()

Để ngăn ngừa lỗi này, bạn có thể sử dụng 'use strict';chỉ thị:

'use strict';
var undefined = 'hello';
var test = undefined;
console.log(typeof test);

Nếu bạn đang viết mã nơi bạn không thể kiểm soát nơi nó sẽ được thực thi (ví dụ: thư viện, nhúng, v.v.) thì đó là một mô hình tốt để sử dụng IIFE để bạn có thể đảm bảo rằng không xác định sẽ luôn chính xác / có thể sử dụng được. Đây là một ví dụ:

(function(undefined){
  // undefined will equal `undefined` because we didn't pass in an argument to the IIFE
  
  console.log(undefined); // always `undefined`, even if undefined !== `undefined`outside of the IIFE scope
})(); // No argument supplied


Tất cả các thử nghiệm của tôi đã được thực hiện bằng Firefox 72.0b10 (64 bit) trên Ubuntu và kết quả cho đoạn mã đầu tiên có thể khác nhau trên một trình duyệt cũ hơn.


3
@pmiranda không phải của tôi, thấy nó rất thú vị
jonatjano

2
Cảm ơn một lần nữa. Tất cả sự nghi ngờ này có nguồn gốc từ điều này: một nhà phát triển mới ở đây đã dịch một số biến tên tiếng Tây Ban Nha sang tiếng Anh. Trong mã của chúng tôi, chúng tôi đã có một biến được gọi là let indefinido= dataArray( (a) => (anotherArray.includes(someName)));chúng tôi đang kiểm tra xem var đó có "không xác định" (kết quả findkhông tìm thấy phần tử nào) hay không. Sau đó, anh dịch indefinidocho undefinedtôi thấy rằng tôi đã thử nghiệm nó trên Chrome và Edge, thấy một số khác biệt. Đó là lý do tại sao tôi đến đây để hỏi ý kiến ​​của những người còn lại, vì tôi cũng đang học.
pmiranda

@pmiranda Câu trả lời này không trả lời đúng phần "tại sao". Nhưng đó là một câu trả lời tốt.
Ismael Miguel

2
Nếu cuối cùng bạn cần giá trị thực của không xác định, hãy sử dụngvoid 0
Người dùng không phải là người dùng

2
@Jon vì một số lý do , Hiệp hội Ecmascript đã chọn không đặt từ khóa không xác định mà là một thuộc tính của đối tượng toàn cầu
jonatjano

17

Mặc dù có thể sử dụng nó làm định danh (tên biến) trong bất kỳ phạm vi nào ngoài phạm vi toàn cầu (vì không xác định không phải là từ dành riêng), làm như vậy là một ý tưởng rất tệ sẽ khiến mã của bạn khó duy trì và gỡ lỗi.

Nguồn https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/und xác định

undefinedkhông dành riêng vì thế chúng ta có thể gán cho nó một giá trị mới.

Khi bạn không sử dụng, strict modevề cơ bản bạn đang tạo một biến được gọi undefinedtrong phạm vi cục bộ và gán stringgiá trị cho nó.

undefinedlà một tài sản của đối tượng toàn cầu . Giá trị ban đầu của không xác định là giá trị nguyên thủyundefined.

use strict sẽ giúp ngăn ngừa lỗi này trong phạm vi toàn cầu trong khi nó vẫn có thể được ghi đè trong phạm vi địa phương.

Nếu bạn muốn an toàn hơn, bạn nên sử dụng void 0thay vì undefined luôn luôn trả lại undefined.

'use stict'

const test = (() => {
  let undefined = "test"
  console.log(typeof undefined)
  console.log(typeof void 0)
})()


1
đây là danh sách từ khóa để biết thêm chi tiết
jonatjano

1
Đáng lưu ý rằng trong một IIFE như vậy, người ta cũng có thể có được một tài liệu tham khảo undefinedbằng cách đọc nó như là một đối số. Vì IIFE không bao giờ được thông qua bất kỳ đối số nào ở đây, họ sẽ undefinedở trong đó. Ví dụ:((undefined) => console.log(typeof undefined))()
SeinopSys
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.