Tại sao chức năng JavaScript của tôi không được xác định?

So với các ngôn ngữ khác, khái niệm không xác định của JavaScript hơi khó hiểu. Đặc biệt, cố gắng hiểu ReferenceErrors (“x không được xác định”) và cách tốt nhất để viết mã chống lại chúng có thể gây khó chịu

Đây là nỗ lực của tôi để giải quyết mọi thứ một chút. Nếu bạn chưa quen với sự khác biệt giữa biến và thuộc tính trong JavaScript (bao gồm cả Biến đối tượng bên trong) thì bây giờ có thể là thời điểm tốt để xem bài đăng trước của tôi

Không xác định là gì?

Trong JavaScript có Không xác định (loại), không xác định (giá trị) và không xác định (biến).

Không xác định (loại) là một loại JavaScript tích hợp.

không xác định (giá trị) là nguyên thủy và là giá trị duy nhất của loại Không xác định. Bất kỳ thuộc tính nào chưa được gán giá trị, giả sử giá trị

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
2. (ECMA4. 3. 9 và 4. 3. 10). Hàm không có câu lệnh trả về hoặc hàm có câu lệnh trả về trống trả về không xác định. Giá trị của một đối số hàm không được cung cấp là không xác định

var a;
typeof a; //"undefined"

window.b;
typeof window.b; //"undefined"

var c = (function() {})();
typeof c; //"undefined"

var d = (function(e) {return e})();
typeof d; //"undefined"

không xác định (biến) là một thuộc tính toàn cầu có giá trị ban đầu là không xác định (giá trị), Vì đây là thuộc tính toàn cầu nên chúng ta cũng có thể truy cập nó dưới dạng một biến. Để thống nhất, tôi sẽ luôn gọi nó là một biến trong bài viết này

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 

Kể từ ECMA 3, giá trị của nó có thể được gán lại

undefined = "washing machine"; //assign a string to undefined (variable)
typeof undefined //"string"

f = undefined;
typeof f; //"string"
f; //"washing machine"

Không cần phải nói, việc gán lại các giá trị cho biến không xác định là một cách làm rất tồi và trên thực tế, nó không được ECMA 5 cho phép (mặc dù trong số các bản phát hành trình duyệt đầy đủ hiện tại, chỉ có Safari thực thi điều này)

Và sau đó có null?

Có, nói chung là hiểu rõ nhưng đáng nói lại.

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
2 khác với
typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
4, đây cũng là một giá trị nguyên thủy thể hiện sự vắng mặt có chủ ý của một giá trị. Điểm giống nhau duy nhất giữa
typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
2 và
typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
4 là cả hai đều ép buộc sai

Vậy ReferenceError là gì?

ReferenceError chỉ ra rằng giá trị tham chiếu không hợp lệ đã được phát hiện (ECMA 5 15. 11. 6. 3)

Về mặt thực tế, điều này có nghĩa là một ReferenceError sẽ được ném ra khi JavaScript cố gắng lấy giá trị của một tham chiếu không thể giải quyết. (Có những trường hợp khác sẽ xảy ra ReferenceError, đáng chú ý nhất là khi chạy ở chế độ ECMA 5 Strict. Nếu bạn quan tâm, hãy kiểm tra danh sách đọc ở cuối bài viết này)

Lưu ý cách cú pháp tin nhắn khác nhau giữa các trình duyệt. Như chúng ta sẽ thấy không có thông điệp nào trong số này là đặc biệt khai sáng

________số 8

Vẫn chưa rõ ràng…"tài liệu tham khảo không thể giải quyết"?

Theo thuật ngữ ECMA, Tham chiếu bao gồm giá trị cơ sở và tên tham chiếu (ECMA 5 8. 7 - một lần nữa tôi đang lướt qua chế độ nghiêm ngặt. Cũng lưu ý rằng thuật ngữ ECMA 3 thay đổi đôi chút nhưng hiệu quả là như nhau)

Nếu Tham chiếu là một thuộc tính, thì giá trị cơ sở và tên tham chiếu nằm ở hai bên của dấu chấm (hoặc dấu ngoặc đầu tiên hoặc bất kỳ thứ gì)

window.foo; //base value = window, reference name = foo;
a.b; //base value = a, reference name = b;
myObj['create']; // base value = myObj, reference name = 'create';
//Safari, Chrome, IE8+ only
Object.defineProperty(window,"foo", {value: "hello"}); //base value = window, reference name = foo;

Đối với Tham chiếu biến, giá trị cơ sở là Đối tượng biến của ngữ cảnh thực thi hiện tại. Đối tượng biến của bối cảnh toàn cầu là chính đối tượng toàn cầu (

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
7 trong trình duyệt)). Mỗi ngữ cảnh chức năng có một Đối tượng biến trừu tượng được gọi là Đối tượng kích hoạt

var a;
typeof a; //"undefined"

window.b;
typeof window.b; //"undefined"

var c = (function() {})();
typeof c; //"undefined"

var d = (function(e) {return e})();
typeof d; //"undefined"
1

Một tham chiếu được coi là không thể giải quyết nếu giá trị cơ sở của nó không được xác định

Do đó, tham chiếu thuộc tính không thể giải quyết được nếu giá trị trước dấu chấm không được xác định. Ví dụ sau sẽ đưa ra ReferenceError nhưng không phải vì TypeError xuất hiện trước. Điều này là do giá trị cơ bản của thuộc tính tuân theo CheckObjectCoercible (ECMA 5 9. 10 qua 11. 2. 1) ném TypeError khi cố gắng chuyển đổi loại Không xác định thành Đối tượng. (cảm ơn kangax về mẹo đăng trước qua twitter)

var a;
typeof a; //"undefined"

window.b;
typeof window.b; //"undefined"

var c = (function() {})();
typeof c; //"undefined"

var d = (function(e) {return e})();
typeof d; //"undefined"
2

Tham chiếu biến sẽ không bao giờ là không thể giải quyết được vì từ khóa var đảm bảo Biến đối tượng luôn được gán cho giá trị cơ sở

Các tham chiếu không phải là thuộc tính hoặc biến theo định nghĩa là không thể giải quyết được và sẽ đưa ra ReferenceError

var a;
typeof a; //"undefined"

window.b;
typeof window.b; //"undefined"

var c = (function() {})();
typeof c; //"undefined"

var d = (function(e) {return e})();
typeof d; //"undefined"
3

JavaScript không thấy giá trị cơ sở rõ ràng và do đó tra cứu Biến đối tượng cho thuộc tính có tên tham chiếu 'foo'. Không tìm thấy nó xác định 'foo' không có giá trị cơ sở và đưa ra ReferenceError

Nhưng không phải
typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
8 chỉ là một biến không được khai báo sao?

kỹ thuật không. Mặc dù đôi khi chúng ta thấy “biến không được khai báo” là một thuật ngữ hữu ích để chẩn đoán lỗi, nhưng trên thực tế, một biến không phải là một biến cho đến khi nó được khai báo.

Điều gì về toàn cầu tiềm ẩn?

Đó là sự thật, các định danh không bao giờ được khai báo bằng từ khóa var sẽ được tạo dưới dạng biến toàn cục – nhưng chỉ khi chúng là đối tượng của một phép gán

var a;
typeof a; //"undefined"

window.b;
typeof window.b; //"undefined"

var c = (function() {})();
typeof c; //"undefined"

var d = (function(e) {return e})();
typeof d; //"undefined"
5

Điều này, tất nhiên, gây phiền nhiễu. Sẽ tốt hơn nếu JavaScript liên tục ném ReferenceErrors khi nó gặp phải các tham chiếu không thể giải quyết được (và thực tế đây là những gì nó làm trong Chế độ nghiêm ngặt ECMA)

Khi nào tôi cần viết mã chống lại ReferenceErrors?

Nếu mã của bạn là âm thanh, rất hiếm khi. Chúng ta đã thấy rằng trong cách sử dụng thông thường, chỉ có một cách duy nhất để có được một tham chiếu không thể giải quyết được. sử dụng Tham chiếu đúng cú pháp không phải là thuộc tính hoặc biến. Trong hầu hết các trường hợp, tình huống này có thể tránh được bằng cách đảm bảo bạn nhớ từ khóa var. Lần duy nhất bạn có thể gặp bất ngờ trong thời gian chạy là khi tham chiếu các biến chỉ tồn tại trong một số trình duyệt nhất định hoặc mã của bên thứ 3

Một ví dụ điển hình là bảng điều khiển. Trong các trình duyệt Webkit, bảng điều khiển được tích hợp sẵn và thuộc tính bảng điều khiển luôn khả dụng. Bảng điều khiển Firefox phụ thuộc vào Firebug (hoặc các tiện ích bổ sung khác) được cài đặt và bật. IE7 không có bảng điều khiển, IE8 có bảng điều khiển nhưng thuộc tính bảng điều khiển chỉ tồn tại khi Công cụ dành cho nhà phát triển IE được khởi động. Rõ ràng Opera có bảng điều khiển nhưng tôi chưa bao giờ làm cho nó hoạt động 😉

Kết quả cuối cùng là rất có thể đoạn mã sau sẽ đưa ra ReferenceError khi chạy trong trình duyệt

var a;
typeof a; //"undefined"

window.b;
typeof window.b; //"undefined"

var c = (function() {})();
typeof c; //"undefined"

var d = (function(e) {return e})();
typeof d; //"undefined"
6

Làm cách nào để mã hóa các biến có thể không tồn tại?

Một cách để kiểm tra một tham chiếu không thể giải quyết mà không ném ReferenceError là sử dụng từ khóa

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
9

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
0

Tuy nhiên, điều này luôn có vẻ dài dòng đối với tôi, chưa kể đến sự đáng ngờ (không phải tên tham chiếu không được xác định, mà là giá trị cơ sở) và dù sao thì tôi cũng muốn dành

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
9 để kiểm tra loại tích cực

May mắn thay, có một giải pháp thay thế. chúng tôi đã biết rằng các thuộc tính không xác định sẽ không đưa ra ReferenceError cung cấp giá trị cơ sở của chúng được xác định- và vì bảng điều khiển thuộc về đối tượng toàn cầu, chúng tôi chỉ có thể làm điều này

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
1

Trên thực tế, bạn chỉ cần kiểm tra sự tồn tại của biến trong ngữ cảnh chung (các ngữ cảnh thực thi khác tồn tại trong các hàm và bạn kiểm soát những biến nào tồn tại trong các hàm của riêng bạn). Vì vậy, về lý thuyết, ít nhất bạn sẽ có thể thoát khỏi mà không cần sử dụng kiểm tra

typeof undefined; //"undefined"

var f = 2;
f = undefined; //re-assigning to undefined (variable)
typeof f; //"undefined" 
9 đối với ReferenceError

Tại sao JavaScript không được xác định?

Thuộc tính không xác định cho biết rằng một biến chưa được gán giá trị hoặc hoàn toàn không được khai báo .

Tại sao tham số JavaScript không được xác định?

Trong JavaScript, tham số có giá trị mặc định là không xác định. Điều đó có nghĩa là nếu bạn không truyền đối số vào hàm , các tham số của nó sẽ có giá trị mặc định là không xác định. Hàm say() nhận tham số thông báo.

Tại sao bảng điều khiển JavaScript không được xác định?

Điều này là do bảng điều khiển. log() không trả về giá trị (tôi. e. trả về không xác định). Kết quả của bất kỳ thứ gì bạn đã nhập vào bảng điều khiển trước tiên được in ra bảng điều khiển, sau đó một lát là thông báo từ bảng điều khiển.