Cách tốt nhất để kiểm tra xem một thuộc tính đối tượng trong JavaScript là undefined
gì?
Cách tốt nhất để kiểm tra xem một thuộc tính đối tượng trong JavaScript là undefined
gì?
Câu trả lời:
Cách thông thường để kiểm tra xem giá trị của tài sản có phải là giá trị đặc biệt hay không undefined
, là:
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
Để kiểm tra xem một đối tượng không thực sự có thuộc tính như vậy hay không, và do đó sẽ trả về undefined
theo mặc định khi bạn thử và truy cập vào nó:
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
Để kiểm tra xem giá trị gắn liền với một định danh là giá trị đặc biệt undefined
, hoặc nếu định danh mà chưa được công bố. Lưu ý: phương pháp này là cách duy nhất để đề cập đến một mã định danh chưa được khai báo (lưu ý: khác với việc có giá trị undefined
) mà không có lỗi sớm:
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
Trong các phiên bản JavaScript trước ECMAScript 5, thuộc tính có tên "không xác định" trên đối tượng toàn cầu có thể ghi được và do đó, một kiểm tra đơn giản foo === undefined
có thể hoạt động bất ngờ nếu nó vô tình được xác định lại. Trong JavaScript hiện đại, thuộc tính chỉ đọc.
Tuy nhiên, trong JavaScript hiện đại, "không xác định" không phải là một từ khóa và do đó, các biến bên trong các hàm có thể được đặt tên là "không xác định" và phủ bóng lên thuộc tính toàn cầu.
Nếu bạn lo lắng về trường hợp cạnh (không chắc) này, bạn có thể sử dụng toán tử void để nhận undefined
giá trị đặc biệt :
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
obj !== undefined
ngay bây giờ. undefined
đã từng là đột biến, giống như undefined = 1234
những gì sẽ gây ra kết quả thú vị. Nhưng sau Ecmascript 5, nó không thể ghi được nữa, vì vậy chúng ta có thể sử dụng phiên bản đơn giản hơn. codereadability.com/how-to-check-for-undinite-in-javascript
Tôi tin rằng có một số câu trả lời không chính xác cho chủ đề này. Trái với suy nghĩ thông thường, "không xác định" không phải là một từ khóa trong JavaScript và trên thực tế có thể có một giá trị được gán cho nó.
Cách mạnh mẽ nhất để thực hiện kiểm tra này là:
if (typeof myVar === "undefined")
Điều này sẽ luôn trả về kết quả chính xác và thậm chí xử lý tình huống myVar
không được khai báo.
var undefined = false; // Shockingly, this is completely legal!
if (myVar === undefined) {
alert("You have been misled. Run away!");
}
Ngoài ra, myVar === undefined
sẽ phát sinh lỗi trong trường hợp myVar không được khai báo.
=== undefined
hoang mang. Có, bạn có thể gán cho undefined
, nhưng không có lý do chính đáng để làm như vậy và có thể dự đoán rằng làm như vậy có thể phá vỡ mã của bạn. Trong C bạn có thể #define true false
và trong Python bạn có thể gán cho True
và False
, nhưng mọi người không cảm thấy cần phải thiết kế mã của họ bằng các ngôn ngữ đó để bảo vệ chống lại khả năng chính họ cố tình phá hoại môi trường của chính họ ở nơi khác trong mã . Tại sao khả năng gán cho undefined
thậm chí đáng xem xét ở đây?
void 0
để có được giá trị mà undefined
điểm. Vì vậy, bạn có thể làm if (myVar === void 0)
. Điều 0
này không đặc biệt, bạn có thể đặt bất kỳ biểu thức nào ở đó.
undefined
nữa. MDN: không xác định
Mặc dù được đề nghị kịch liệt bởi nhiều câu trả lời khác ở đây, typeof
là một lựa chọn tồi . Không bao giờ nên sử dụng nó để kiểm tra xem các biến có giá trị hay không undefined
, bởi vì nó hoạt động như một kiểm tra kết hợp cho giá trị undefined
và cho dù một biến có tồn tại hay không. Trong phần lớn các trường hợp, bạn biết khi nào một biến tồn tại và typeof
sẽ chỉ giới thiệu khả năng thất bại thầm lặng nếu bạn tạo một lỗi đánh máy trong tên biến hoặc trong chuỗi ký tự 'undefined'
.
var snapshot = …;
if (typeof snaposhot === 'undefined') {
// ^
// misspelled¹ – this will never run, but it won’t throw an error!
}
var foo = …;
if (typeof foo === 'undefned') {
// ^
// misspelled – this will never run, but it won’t throw an error!
}
Vì vậy, trừ khi bạn đang thực hiện tính năng phát hiện², trong đó không chắc chắn liệu tên đã cho có nằm trong phạm vi hay không (như kiểm tra typeof module !== 'undefined'
dưới dạng một bước trong mã cụ thể cho môi trường CommonJS), typeof
là một lựa chọn có hại khi được sử dụng trên một biến và tùy chọn chính xác là để so sánh trực tiếp giá trị:
var foo = …;
if (foo === undefined) {
⋮
}
Một số quan niệm sai lầm phổ biến về điều này bao gồm:
rằng việc đọc một biến số chưa được khởi tạo ( var foo
) hoặc tham số ( function bar(foo) { … }
được gọi là bar()
) sẽ không thành công. Điều này chỉ đơn giản là không đúng - các biến không có khởi tạo rõ ràng và các tham số không được cung cấp giá trị luôn luôn trở thành undefined
và luôn nằm trong phạm vi.
Điều đó undefined
có thể được ghi đè. Có nhiều hơn thế này. undefined
không phải là một từ khóa trong JavaScript. Thay vào đó, nó là một thuộc tính trên đối tượng toàn cầu với giá trị Không xác định. Tuy nhiên, kể từ ES5, thuộc tính này chỉ đọc và không thể định cấu hình . Không có trình duyệt hiện đại nào sẽ cho phép undefined
thay đổi tài sản và kể từ năm 2017, điều này đã xảy ra trong một thời gian dài. Thiếu chế độ nghiêm ngặt cũng không ảnh hưởng đến undefined
hành vi của nó - nó chỉ đưa ra những tuyên bố như undefined = 5
không làm gì thay vì ném. Tuy nhiên, vì đó không phải là một từ khóa, bạn có thể khai báo các biến bằng tên undefined
và các biến đó có thể được thay đổi, tạo nên mô hình phổ biến này:
(function (undefined) {
// …
})()
nhiều nguy hiểm hơn bằng cách sử dụng toàn cầu undefined
. Nếu bạn phải tương thích ES3, hãy thay thế undefined
bằng void 0
- không dùng đến typeof
. ( void
luôn luôn là một toán tử đơn nguyên đánh giá giá trị Không xác định cho bất kỳ toán hạng nào.)
Với cách các biến hoạt động theo cách khác, đã đến lúc giải quyết câu hỏi thực tế: thuộc tính đối tượng. Không có lý do để sử dụng typeof
cho các thuộc tính đối tượng. Ngoại lệ trước đó liên quan đến phát hiện tính năng không áp dụng ở đây - typeof
chỉ có hành vi đặc biệt đối với các biến và các biểu thức mà thuộc tính đối tượng tham chiếu không phải là biến.
Điều này:
if (typeof foo.bar === 'undefined') {
⋮
}
là luôn luôn chính xác tương đương để this³:
if (foo.bar === undefined) {
⋮
}
và xem xét lời khuyên ở trên, để tránh gây nhầm lẫn cho người đọc về lý do tại sao bạn sử dụng typeof
, bởi vì nó hợp lý nhất để sử dụng ===
để kiểm tra sự bằng nhau, bởi vì nó có thể được tái cấu trúc để kiểm tra giá trị của biến sau đó và vì nó chỉ đơn giản có vẻ tốt hơn, bạn nên luôn luôn sử dụng === undefined
³ ở đây .
Một cái gì đó khác để xem xét khi nói đến các thuộc tính đối tượng là liệu bạn có thực sự muốn kiểm tra hay không undefined
. Tên thuộc tính đã cho có thể vắng mặt trên một đối tượng (tạo ra giá trị undefined
khi đọc), xuất hiện trên chính đối tượng đó với giá trị undefined
, xuất hiện trên nguyên mẫu của đối tượng với giá trị undefined
hoặc xuất hiện trên một trong những đối tượng không có undefined
giá trị. 'key' in obj
sẽ cho bạn biết liệu một khóa có ở bất cứ đâu trên chuỗi nguyên mẫu của đối tượng hay không và Object.prototype.hasOwnProperty.call(obj, 'key')
sẽ cho bạn biết liệu nó có trực tiếp trên đối tượng hay không. Mặc dù vậy, tôi sẽ không đi vào chi tiết trong câu trả lời này về các nguyên mẫu và sử dụng các đối tượng làm bản đồ có khóa, bởi vì nó chủ yếu nhằm chống lại tất cả các lời khuyên tồi trong các câu trả lời khác bất kể các cách hiểu có thể có của câu hỏi ban đầu. Đọc lênnguyên mẫu đối tượng trên MDN để biết thêm!
Lựa chọn bất thường của tên biến ví dụ? đây là mã chết thực sự từ tiện ích mở rộng NoScript cho Firefox.
Mặc dù vậy, ² đừng cho rằng không biết những gì trong phạm vi nói chung là ổn. lỗ hổng phần thưởng gây ra do lạm dụng phạm vi động: Project Zero 1225
³ một lần nữa giả định môi trường ES5 + và điều đó undefined
đề cập đến undefined
tài sản của đối tượng toàn cầu. thay thế void 0
khác.
undefined
, ẩn bối cảnh mặc định. Mà cho hầu hết các mục đích thực tế có tác dụng tương tự như ghi đè lên nó.
void 0
để so sánh với không xác định nhưng một lần nữa - đó là điều ngớ ngẩn và quá mức cần thiết.
typeof something === "undefined")
trong mã.
void 0
là (một lần) vừa ngắn hơn và an toàn hơn! Đó là một chiến thắng trong cuốn sách của tôi.
Trong JavaScript có null và không xác định . Chúng có ý nghĩa khác nhau.
Marijn Haverbeke tuyên bố, trong cuốn sách trực tuyến miễn phí " Eloquent JavaScript " (nhấn mạnh của tôi):
Ngoài ra còn có một giá trị tương tự, null, có nghĩa là 'giá trị này được xác định, nhưng nó không có giá trị'. Sự khác biệt về ý nghĩa giữa không xác định và null chủ yếu là học thuật, và thường không thú vị lắm. Trong các chương trình thực tế, thường cần kiểm tra xem một cái gì đó 'có giá trị' hay không. Trong những trường hợp này, biểu thức Something == không xác định có thể được sử dụng, bởi vì, mặc dù chúng không chính xác cùng một giá trị, null == không xác định sẽ tạo ra đúng.
Vì vậy, tôi đoán cách tốt nhất để kiểm tra nếu một cái gì đó không được xác định sẽ là:
if (something == undefined)
Hi vọng điêu nay co ich!
Chỉnh sửa: Để đáp ứng với chỉnh sửa của bạn, các thuộc tính đối tượng sẽ hoạt động theo cùng một cách.
var person = {
name: "John",
age: 28,
sex: "male"
};
alert(person.name); // "John"
alert(person.fakeVariable); // undefined
undefined
chỉ là một biến có thể được gán lại bởi người dùng: viết undefined = 'a';
sẽ khiến mã của bạn không còn làm những gì bạn nghĩ. Sử dụng typeof
là tốt hơn và cũng hoạt động cho các biến (không chỉ các thuộc tính) chưa được khai báo.
Điều này có nghĩa là gì: "thuộc tính đối tượng không xác định" ?
Thật ra nó có thể có nghĩa là hai điều khá khác nhau! Đầu tiên, nó có thể có nghĩa là thuộc tính chưa bao giờ được xác định trong đối tượng và thứ hai, nó có thể có nghĩa là thuộc tính có giá trị không xác định . Hãy xem mã này:
var o = { a: undefined }
Là o.a
không xác định? Đúng! Giá trị của nó là không xác định. Là o.b
không xác định? Chắc chắn rồi! Không có tài sản 'b' nào cả! OK, xem bây giờ cách tiếp cận khác nhau hành xử trong cả hai tình huống:
typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false
Chúng ta có thể thấy rõ điều đó typeof obj.prop == 'undefined'
và obj.prop === undefined
tương đương, và chúng không phân biệt các tình huống khác nhau đó. Và 'prop' in obj
có thể phát hiện tình huống khi một tài sản chưa được xác định và không chú ý đến giá trị tài sản có thể không được xác định.
1) Bạn muốn biết nếu một tài sản không được xác định bởi ý nghĩa thứ nhất hoặc thứ hai (tình huống điển hình nhất).
obj.prop === undefined // IMHO, see "final fight" below
2) Bạn muốn biết liệu đối tượng có một số tài sản và không quan tâm đến giá trị của nó.
'prop' in obj
x.a === undefined
hoặc cái này typeof x.a == 'undefined'
tăng ReferenceError: x is not defined
nếu x không được xác định.undefined
là một biến toàn cục (vì vậy thực sự nó nằm window.undefined
trong trình duyệt). Nó đã được hỗ trợ kể từ ECMAScript 1st Edition và kể từ ECMAScript 5, nó chỉ được đọc . Vì vậy, trong các trình duyệt hiện đại, nó không thể được định nghĩa lại thành sự thật vì nhiều tác giả thích làm chúng ta sợ hãi, nhưng điều này vẫn đúng với các trình duyệt cũ hơn.obj.prop === undefined
vstypeof obj.prop == 'undefined'
Điểm cộng của obj.prop === undefined
:
undefined
Điểm trừ của obj.prop === undefined
:
undefined
có thể bị ghi đè trong các trình duyệt cũĐiểm cộng của typeof obj.prop == 'undefined'
:
Điểm trừ của typeof obj.prop == 'undefined'
:
'undefned'
( sai chính tả ) ở đây chỉ là một chuỗi hằng, vì vậy công cụ JavaScript không thể giúp bạn nếu bạn viết sai chính tả như tôi vừa làm.Node.js hỗ trợ biến toàn cục undefined
là global.undefined
(nó cũng có thể được sử dụng mà không có tiền tố 'toàn cầu'). Tôi không biết về các triển khai JavaScript phía máy chủ khác.
undefined
là thành viên của global
. Cũng không phải console.log(global);
cũng for (var key in global) { ... }
không hiển thị không xác định là một thành viên của toàn cầu . Nhưng kiểm tra như 'undefined' in global
thể hiện điều ngược lại.
[[Enumerable]]
là sai :-)
Minuses of typeof obj.prop == 'undefined'
, điều này có thể tránh được bằng cách viết như typeof obj.prop == typeof undefined
. Điều này cũng cho một đối xứng rất tốt đẹp.
obj.prop === undefined
.
if ('foo' in o
) câu trả lời đúng đầu tiên ở đây. Khá nhiều người khác chỉ trả lời câu đó.
Vấn đề sôi xuống đến ba trường hợp:
undefined
.undefined
.Điều này cho chúng tôi biết một số điều tôi cho là quan trọng:
Có một sự khác biệt giữa một thành viên không xác định và một thành viên được xác định với một giá trị không xác định.
Nhưng typeof obj.foo
thật không may không cho chúng ta biết trường hợp nào trong ba trường hợp chúng ta có. Tuy nhiên chúng ta có thể kết hợp điều này với "foo" in obj
để phân biệt các trường hợp.
| typeof obj.x === 'undefined' | !("x" in obj)
1. { x:1 } | false | false
2. { x : (function(){})() } | true | false
3. {} | true | true
Cần lưu ý rằng các bài kiểm tra này là giống nhau cho null
các mục quá
| typeof obj.x === 'undefined' | !("x" in obj)
{ x:null } | false | false
Tôi cho rằng trong một số trường hợp, sẽ hợp lý hơn (và rõ ràng hơn) để kiểm tra xem tài sản có ở đó hay không, hơn là kiểm tra xem nó có được xác định không, và trường hợp duy nhất mà kiểm tra này sẽ khác là trường hợp 2, trường hợp hiếm gặp của một mục thực tế trong đối tượng với một giá trị không xác định.
Ví dụ: Tôi vừa mới cấu trúc lại một loạt mã có một loạt các kiểm tra xem một đối tượng có thuộc tính cụ thể không.
if( typeof blob.x != 'undefined' ) { fn(blob.x); }
Mà rõ ràng hơn khi được viết mà không cần kiểm tra không xác định.
if( "x" in blob ) { fn(blob.x); }
Nhưng như đã được đề cập, những thứ này không hoàn toàn giống nhau (nhưng quá đủ tốt cho nhu cầu của tôi).
if (!("x" in blob)) {}
với dấu ngoặc quanh, vì! toán tử được ưu tiên hơn 'in'. Hy vọng rằng sẽ giúp được ai đó.
a = {b: undefined}
; sau đó typeof a.b === typeof a.c === 'undefined'
nhưng 'b' in a
và !('c' in a)
.
{ x : undefined }
hoặc ít nhất là thêm điểm đó như một cách thay thế khác cho (2.) trong bảng - Tôi phải suy nghĩ một lúc để nhận ra điểm đó (2.) đánh giá undefined
(mặc dù bạn đề cập đến điều đó sau này).
if ( typeof( something ) == "undefined")
Điều này làm việc cho tôi trong khi những người khác thì không.
typeof (something == "undefined")
.
(typeof something) === "undefined"
.
Tôi không chắc nguồn gốc của việc sử dụng ===
với typeof
từ đâu và như một quy ước tôi thấy nó được sử dụng trong nhiều thư viện, nhưng toán tử typeof trả về một chuỗi ký tự và chúng tôi biết điều đó ở phía trước, vậy tại sao bạn cũng muốn gõ kiểm tra nó quá?
typeof x; // some string literal "string", "object", "undefined"
if (typeof x === "string") { // === is redundant because we already know typeof returns a string literal
if (typeof x == "string") { // sufficient
==
vẫn yêu cầu ít nhất một kiểm tra kiểu - trình thông dịch không thể so sánh hai toán hạng mà không biết loại của chúng trước.
==
là một nhân vật ít hơn ===
:)
Viết chéo câu trả lời của tôi từ câu hỏi liên quan Làm thế nào để kiểm tra "không xác định" trong JavaScript?
Cụ thể cho câu hỏi này, xem trường hợp thử nghiệm với someObject.<whatever>
.
Một số tình huống minh họa kết quả của các câu trả lời khác nhau: http://jsfiddle.net/drzaus/UVjM4/
(Lưu ý rằng việc sử dụng var
để in
kiểm tra tạo ra sự khác biệt khi trong trình bao bọc có phạm vi)
Mã để tham khảo:
(function(undefined) {
var definedButNotInitialized;
definedAndInitialized = 3;
someObject = {
firstProp: "1"
, secondProp: false
// , undefinedProp not defined
}
// var notDefined;
var tests = [
'definedButNotInitialized in window',
'definedAndInitialized in window',
'someObject.firstProp in window',
'someObject.secondProp in window',
'someObject.undefinedProp in window',
'notDefined in window',
'"definedButNotInitialized" in window',
'"definedAndInitialized" in window',
'"someObject.firstProp" in window',
'"someObject.secondProp" in window',
'"someObject.undefinedProp" in window',
'"notDefined" in window',
'typeof definedButNotInitialized == "undefined"',
'typeof definedButNotInitialized === typeof undefined',
'definedButNotInitialized === undefined',
'! definedButNotInitialized',
'!! definedButNotInitialized',
'typeof definedAndInitialized == "undefined"',
'typeof definedAndInitialized === typeof undefined',
'definedAndInitialized === undefined',
'! definedAndInitialized',
'!! definedAndInitialized',
'typeof someObject.firstProp == "undefined"',
'typeof someObject.firstProp === typeof undefined',
'someObject.firstProp === undefined',
'! someObject.firstProp',
'!! someObject.firstProp',
'typeof someObject.secondProp == "undefined"',
'typeof someObject.secondProp === typeof undefined',
'someObject.secondProp === undefined',
'! someObject.secondProp',
'!! someObject.secondProp',
'typeof someObject.undefinedProp == "undefined"',
'typeof someObject.undefinedProp === typeof undefined',
'someObject.undefinedProp === undefined',
'! someObject.undefinedProp',
'!! someObject.undefinedProp',
'typeof notDefined == "undefined"',
'typeof notDefined === typeof undefined',
'notDefined === undefined',
'! notDefined',
'!! notDefined'
];
var output = document.getElementById('results');
var result = '';
for(var t in tests) {
if( !tests.hasOwnProperty(t) ) continue; // bleh
try {
result = eval(tests[t]);
} catch(ex) {
result = 'Exception--' + ex;
}
console.log(tests[t], result);
output.innerHTML += "\n" + tests[t] + ": " + result;
}
})();
Và kết quả:
definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined
Nếu bạn làm
if (myvar == undefined )
{
alert('var does not exists or is not initialized');
}
nó sẽ thất bại khi biến myvar
không tồn tại, vì myvar không được xác định, do đó tập lệnh bị hỏng và thử nghiệm không có hiệu lực.
Vì đối tượng cửa sổ có phạm vi toàn cầu (đối tượng mặc định) bên ngoài hàm, nên một khai báo sẽ được 'đính kèm' vào đối tượng cửa sổ.
Ví dụ:
var myvar = 'test';
Biến toàn cầu myvar giống như window.myvar hoặc window ['myvar']
Để tránh lỗi kiểm tra khi tồn tại một biến toàn cục, bạn nên sử dụng tốt hơn:
if(window.myvar == undefined )
{
alert('var does not exists or is not initialized');
}
Câu hỏi nếu một biến thực sự tồn tại không thành vấn đề, giá trị của nó là không chính xác. Mặt khác, thật ngớ ngẩn khi khởi tạo các biến không xác định và tốt hơn là sử dụng giá trị false để khởi tạo. Khi bạn biết rằng tất cả các biến mà bạn khai báo được khởi tạo bằng false, bạn chỉ cần kiểm tra loại của nó hoặc dựa vào !window.myvar
để kiểm tra xem nó có giá trị phù hợp / hợp lệ hay không. Vì vậy, ngay cả khi các biến không được định nghĩa sau đó !window.myvar
là như nhau cho myvar = undefined
hay myvar = false
hay myvar = 0
.
Khi bạn mong đợi một loại cụ thể, hãy kiểm tra loại của biến. Để tăng tốc độ kiểm tra một điều kiện tốt hơn bạn nên làm:
if( !window.myvar || typeof window.myvar != 'string' )
{
alert('var does not exists or is not type of string');
}
Khi điều kiện đầu tiên và đơn giản là đúng, trình thông dịch bỏ qua các bài kiểm tra tiếp theo.
Luôn luôn tốt hơn là sử dụng thể hiện / đối tượng của biến để kiểm tra xem nó có giá trị hợp lệ hay không. Nó ổn định hơn và là một cách lập trình tốt hơn.
(y)
Tôi đã không nhìn thấy (hy vọng tôi đã không bỏ lỡ nó) bất cứ ai kiểm tra đối tượng trước tài sản. Vì vậy, đây là ngắn nhất và hiệu quả nhất (mặc dù không nhất thiết phải rõ ràng nhất):
if (obj && obj.prop) {
// Do something;
}
Nếu obj hoặc obj.prop không được xác định, null hoặc "falsy", câu lệnh if sẽ không thực thi khối mã. Đây thường là hành vi mong muốn trong hầu hết các câu lệnh chặn mã (trong JavaScript).
var x = obj && obj.prop || 'default';
Trong bài viết Khám phá Vực thẳm của Null và Không xác định trong JavaScript, tôi đọc rằng các khung như Underscore.js sử dụng chức năng này:
function isUndefined(obj){
return obj === void 0;
}
void 0
chỉ là một cách viết ngắn undefined
(vì đó là khoảng trống theo sau bởi bất kỳ biểu thức nào trả về), nó lưu 3 charcters. Nó cũng có thể làm được var a; return obj === a;
, nhưng đó là một nhân vật nữa. :-)
void
là một từ dành riêng, trong khi undefined
không có nghĩa là trong khi undefined
bằng với void 0
mặc định, bạn có thể gán một giá trị cho undefined
ví dụ undefined = 1234
.
isUndefined(obj)
: 16 ký tự. obj === void 0
: 14 ký tự. 'nói không hay.
Đơn giản là mọi thứ không được định nghĩa trong JavaScript, không được xác định , không thành vấn đề nếu đó là một thuộc tính bên trong Object / Array hoặc chỉ là một biến đơn giản ...
JavaScript typeof
giúp dễ dàng phát hiện một biến không xác định.
Đơn giản chỉ cần kiểm tra nếu typeof whatever === 'undefined'
và nó sẽ trả về một boolean.
Đó là cách hàm nổi tiếng isUndefined()
trong AngularJs v.1x được viết:
function isUndefined(value) {return typeof value === 'undefined';}
Vì vậy, khi bạn thấy hàm nhận một giá trị, nếu giá trị đó được xác định, nó sẽ trả về false
, nếu không, đối với các giá trị không xác định, trả về true
.
Vì vậy, hãy xem kết quả sẽ như thế nào khi chúng ta truyền các giá trị, bao gồm các thuộc tính đối tượng như bên dưới, đây là danh sách các biến chúng ta có:
var stackoverflow = {};
stackoverflow.javascipt = 'javascript';
var today;
var self = this;
var num = 8;
var list = [1, 2, 3, 4, 5];
var y = null;
và chúng tôi kiểm tra chúng như dưới đây, bạn có thể xem kết quả trước mặt chúng dưới dạng nhận xét:
isUndefined(stackoverflow); //false
isUndefined(stackoverflow.javascipt); //false
isUndefined(today); //true
isUndefined(self); //false
isUndefined(num); //false
isUndefined(list); //false
isUndefined(y); //false
isUndefined(stackoverflow.java); //true
isUndefined(stackoverflow.php); //true
isUndefined(stackoverflow && stackoverflow.css); //true
Như bạn thấy, chúng tôi có thể kiểm tra mọi thứ bằng cách sử dụng một cái gì đó như thế này trong mã của chúng tôi, như đã đề cập, bạn chỉ có thể sử dụng typeof
mã của mình, nhưng nếu bạn đang sử dụng nó nhiều lần, hãy tạo một hàm như mẫu góc mà tôi chia sẻ và tiếp tục sử dụng như theo mẫu mã DRY.
Ngoài ra, một điều nữa, để kiểm tra thuộc tính trên một đối tượng trong một ứng dụng thực mà bạn không chắc chắn ngay cả đối tượng có tồn tại hay không, hãy kiểm tra xem đối tượng có tồn tại trước không.
Nếu bạn kiểm tra một thuộc tính trên một đối tượng và đối tượng không tồn tại, sẽ đưa ra lỗi và dừng toàn bộ ứng dụng đang chạy.
isUndefined(x.css);
VM808:2 Uncaught ReferenceError: x is not defined(…)
Rất đơn giản, bạn có thể gói bên trong một câu lệnh if như bên dưới:
if(typeof x !== 'undefined') {
//do something
}
Điều này cũng tương đương với isDefined trong Angular 1.x ...
function isDefined(value) {return typeof value !== 'undefined';}
Ngoài ra, các khung javascript khác như gạch dưới có kiểm tra xác định tương tự, nhưng tôi khuyên bạn nên sử dụng typeof
nếu bạn chưa sử dụng bất kỳ khung nào.
Tôi cũng thêm phần này từ MDN đã có thông tin hữu ích về typeof, không xác định và void (0).
Bình đẳng nghiêm ngặt và không xác định
Bạn có thể sử dụng các toán tử bất đẳng thức và bất đẳng thức nghiêm ngặt để xác định xem một biến có giá trị hay không. Trong đoạn mã sau, biến x không được xác định và câu lệnh if ước lượng là true.
var x;
if (x === undefined) {
// these statements execute
}
else {
// these statements do not execute
}
Lưu ý: Toán tử đẳng thức nghiêm ngặt thay vì toán tử đẳng thức chuẩn phải được sử dụng ở đây, bởi vì x == không xác định cũng kiểm tra xem x có null hay không, trong khi đẳng thức nghiêm ngặt thì không. null không tương đương với không xác định. Xem toán tử so sánh để biết chi tiết.
Toán tử
typeof và không xác định Cách khác, typeof có thể được sử dụng:
var x;
if (typeof x === 'undefined') {
// these statements execute
}
Một lý do để sử dụng typeof là nó không đưa ra lỗi nếu biến chưa được khai báo.
// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
// these statements execute
}
if (x === undefined) { // throws a ReferenceError
}
Tuy nhiên, loại kỹ thuật này nên tránh. JavaScript là một ngôn ngữ có phạm vi tĩnh, do đó, nếu biết một biến được khai báo có thể được đọc bằng cách xem liệu nó có được khai báo trong ngữ cảnh kèm theo hay không. Ngoại lệ duy nhất là phạm vi toàn cầu, nhưng phạm vi toàn cầu bị ràng buộc với đối tượng toàn cầu, do đó, việc kiểm tra sự tồn tại của một biến trong bối cảnh toàn cầu có thể được thực hiện bằng cách kiểm tra sự tồn tại của một thuộc tính trên đối tượng toàn cầu (sử dụng toán tử trong, ví dụ).
Toán tử rỗng và không xác định
Toán tử void là một thay thế thứ ba.
var x;
if (x === void 0) {
// these statements execute
}
// y has not been declared before
if (y === void 0) {
// throws a ReferenceError (in contrast to `typeof`)
}
thêm> ở đây
Nhiều khả năng bạn muốn if (window.x)
. Kiểm tra này an toàn ngay cả khi x chưa được khai báo ( var x;
) - trình duyệt không gặp lỗi.
if (window.history) {
history.call_some_function();
}
cửa sổ là một đối tượng chứa tất cả các biến toàn cục là thành viên của nó và việc cố gắng truy cập một thành viên không tồn tại là hợp pháp. Nếu x chưa được khai báo hoặc chưa được đặt thì window.x
trả về không xác định . không xác định dẫn đến sai khi if () đánh giá nó.
typeof history != 'undefined'
thực sự hoạt động trong cả hai hệ thống.
Đọc qua điều này, tôi ngạc nhiên tôi đã không thấy điều này. Tôi đã tìm thấy nhiều thuật toán sẽ làm việc cho việc này.
Nếu giá trị của một đối tượng không bao giờ được xác định, điều này sẽ ngăn trở lại true
nếu nó được định nghĩa là null
hoặc undefined
. Điều này hữu ích nếu bạn muốn trả về true cho các giá trị được đặt làundefined
if(obj.prop === void 0) console.log("The value has never been defined");
Nếu bạn muốn nó có kết quả như true
đối với các giá trị được xác định bằng giá trị undefined
hoặc không bao giờ được xác định, bạn chỉ cần sử dụng=== undefined
if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");
Thông thường, mọi người đã yêu cầu tôi cho một thuật toán để tìm hiểu xem một giá trị có phải là giả undefined
hay không null
. Các công trình sau đây.
if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
console.log("The value is falsy, null, or undefined");
}
if (!obj.prop)
var obj = {foo: undefined}; obj.foo === void 0
-> true
. Làm thế nào mà "không bao giờ được định nghĩa là undefined
"? Cái này sai.
So sánh với void 0
, cho căng thẳng.
if (foo !== void 0)
Nó không dài dòng như if (typeof foo !== 'undefined')
foo
không được khai báo.
Giải pháp không chính xác. Trong JavaScript,
null == undefined
sẽ trả về true, bởi vì cả hai đều được "cast" thành boolean và là false. Cách chính xác sẽ là kiểm tra
if (something === undefined)
đó là toán tử nhận dạng ...
===
là loại đẳng thức + (đẳng thức nguyên thủy | danh tính đối tượng), trong đó nguyên thủy bao gồm các chuỗi. Tôi nghĩ rằng hầu hết mọi người coi là không 'abab'.slice(0,2) === 'abab'.slice(2)
trực quan nếu một người coi ===
là toán tử nhận dạng.
Bạn có thể nhận được một mảng tất cả không xác định với đường dẫn bằng cách sử dụng mã sau đây.
function getAllUndefined(object) {
function convertPath(arr, key) {
var path = "";
for (var i = 1; i < arr.length; i++) {
path += arr[i] + "->";
}
path += key;
return path;
}
var stack = [];
var saveUndefined= [];
function getUndefiend(obj, key) {
var t = typeof obj;
switch (t) {
case "object":
if (t === null) {
return false;
}
break;
case "string":
case "number":
case "boolean":
case "null":
return false;
default:
return true;
}
stack.push(key);
for (k in obj) {
if (obj.hasOwnProperty(k)) {
v = getUndefiend(obj[k], k);
if (v) {
saveUndefined.push(convertPath(stack, k));
}
}
}
stack.pop();
}
getUndefiend({
"": object
}, "");
return saveUndefined;
}
liên kết jsFiddle
getUndefiend
nên như vậy getUndefined
.
Đây là tình huống của tôi:
Tôi đang sử dụng kết quả của một cuộc gọi REST. Kết quả phải được phân tích cú pháp từ JSON đến một đối tượng JavaScript.
Có một lỗi tôi cần bảo vệ. Nếu các đối số cho cuộc gọi còn lại không chính xác theo như người dùng chỉ định các đối số sai, thì cuộc gọi còn lại về cơ bản là trống.
Trong khi sử dụng bài đăng này để giúp tôi bảo vệ chống lại điều này, tôi đã thử nó.
if( typeof restResult.data[0] === "undefined" ) { throw "Some error"; }
Đối với tình huống của tôi, nếu restResult.data [0] === "đối tượng", thì tôi có thể bắt đầu kiểm tra các thành viên còn lại một cách an toàn. Nếu không xác định thì ném lỗi như trên.
Điều tôi đang nói là đối với tình huống của tôi, tất cả các đề xuất ở trên trong bài đăng này đều không hoạt động. Tôi không nói tôi đúng và mọi người đều sai. Tôi hoàn toàn không phải là một bậc thầy về JavaScript, nhưng hy vọng điều này sẽ giúp được ai đó.
typeof
bảo vệ của bạn không thực sự bảo vệ chống lại bất cứ điều gì mà một so sánh trực tiếp không thể xử lý. Nếu restResult
không được xác định hoặc không được khai báo, nó vẫn sẽ ném.
if(!restResult.data.length) { throw "Some error"; }
Có một cách hay và tao nhã để gán một thuộc tính được xác định cho một biến mới nếu nó được xác định hoặc gán một giá trị mặc định cho nó như một dự phòng nếu nó không xác định.
var a = obj.prop || defaultValue;
Nó phù hợp nếu bạn có một chức năng, nhận một thuộc tính cấu hình bổ sung:
var yourFunction = function(config){
this.config = config || {};
this.yourConfigValue = config.yourConfigValue || 1;
console.log(this.yourConfigValue);
}
Hiện đang thực hiện
yourFunction({yourConfigValue:2});
//=> 2
yourFunction();
//=> 1
yourFunction({otherProperty:5});
//=> 1
Tất cả các câu trả lời là không đầy đủ. Đây là cách đúng để biết rằng có một thuộc tính 'được xác định là không xác định':
var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
} ;
Thí dụ:
var a = { b : 1, e : null } ;
a.c = a.d ;
hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
hasUndefinedProperty(a, 'd') ; // false : d is undefined
hasUndefinedProperty(a, 'e') ; // false : e is defined as null
// And now...
delete a.c ;
hasUndefinedProperty(a, 'c') ; // false : c is undefined
Thật tệ khi đây là câu trả lời đúng bị chôn vùi trong câu trả lời sai> _ <
Vì vậy, đối với bất kỳ ai đi ngang qua, tôi sẽ cung cấp cho bạn không xác định miễn phí !!
var undefined ; undefined ; // undefined
({}).a ; // undefined
[].a ; // undefined
''.a ; // undefined
(function(){}()) ; // undefined
void(0) ; // undefined
eval() ; // undefined
1..a ; // undefined
/a/.a ; // undefined
(true).a ; // undefined
Xem qua các bình luận, đối với những người muốn kiểm tra cả hai thì nó không được xác định hoặc giá trị của nó là null:
//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
alert('either it is undefined or value is null')
}
Nếu bạn đang sử dụng Thư viện jQuery thì jQuery.isEmptyObject()
sẽ đủ cho cả hai trường hợp,
var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;
s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;
//Usage
if (jQuery.isEmptyObject(s)) {
alert('Either variable:s is undefined or its value is null');
} else {
alert('variable:s has value ' + s);
}
s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;
Nếu bạn đang sử dụng Angular:
angular.isUndefined(obj)
angular.isUndefined(obj.prop)
Underscore.js:
_.isUndefined(obj)
_.isUndefined(obj.prop)
1
vào biến x
? Tôi có cần Underscore hoặc jQuery không? (thật ngạc nhiên khi mọi người sẽ sử dụng các thư viện cho ngay cả các hoạt động cơ bản nhất như typeof
kiểm tra)
Tôi sử dụng if (this.variable)
để kiểm tra nếu nó được xác định. Đơn giản if (variable)
, đề nghị ở trên , thất bại cho tôi. Nó chỉ ra rằng nó chỉ hoạt động khi biến là một trường của một đối tượng nào đó, obj.someField
để kiểm tra xem nó có được định nghĩa trong từ điển không. Nhưng chúng ta có thể sử dụng this
hoặc window
làm đối tượng từ điển vì bất kỳ biến nào cũng là một trường trong cửa sổ hiện tại, như tôi hiểu. Vì vậy, đây là một bài kiểm tra
if (this.abc) alert("defined"); else alert("undefined");
abc = "abc";
if (this.abc) alert("defined"); else alert("undefined");
Đầu tiên nó phát hiện biến đó abc
là không xác định và nó được xác định sau khi khởi tạo.
Tôi cung cấp ba cách ở đây cho những người mong đợi câu trả lời kỳ lạ:
function isUndefined1(val) {
try {
val.a;
} catch (e) {
return /undefined/.test(e.message);
}
return false;
}
function isUndefined2(val) {
return !val && val+'' === 'undefined';
}
function isUndefined3(val) {
const defaultVal={};
return ((input=defaultVal)=>input===defaultVal)(val);
}
function test(func){
console.group(`test start :`+func.name);
console.log(func(undefined));
console.log(func(null));
console.log(func(1));
console.log(func("1"));
console.log(func(0));
console.log(func({}));
console.log(func(function () { }));
console.groupEnd();
}
test(isUndefined1);
test(isUndefined2);
test(isUndefined3);
Hãy thử lấy một thuộc tính của giá trị đầu vào, kiểm tra thông báo lỗi nếu nó tồn tại. Nếu giá trị đầu vào không được xác định, thông báo lỗi sẽ là Uncaught TypeError: Không thể đọc thuộc tính 'b' của không xác định
Chuyển đổi giá trị đầu vào thành chuỗi để so sánh "undefined"
và đảm bảo giá trị âm.
Trong js, tham số tùy chọn hoạt động khi giá trị đầu vào chính xác undefined
.
ES2019 đã giới thiệu một tính năng mới - chuỗi tùy chọn mà bạn có thể sử dụng để sử dụng thuộc tính của một đối tượng chỉ khi một đối tượng được xác định như sau:
const userPhone = user?.contactDetails?.phone;
Nó sẽ chỉ tham chiếu đến thuộc tính điện thoại khi người dùng và contactDetails được xác định.
Tham chiếu https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chained
function isUnset(inp) {
return (typeof inp === 'undefined')
}
Trả về false nếu biến được đặt và true nếu không xác định.
Sau đó sử dụng:
if (isUnset(var)) {
// initialize variable here
}
typeof
bài kiểm tra trong một hàm một cách có ý nghĩa . Thật ngạc nhiên khi 4 người ủng hộ điều này. -1.
Tôi muốn cho bạn xem thứ gì đó tôi đang sử dụng để bảo vệ undefined
biến:
Object.defineProperty(window, 'undefined', {});
Điều này cấm mọi người thay đổi window.undefined
giá trị do đó phá hủy mã dựa trên biến đó. Nếu sử dụng "use strict"
, bất cứ điều gì cố gắng thay đổi giá trị của nó sẽ kết thúc bằng lỗi, nếu không nó sẽ bị bỏ qua trong âm thầm.
bạn cũng có thể sử dụng Proxy, nó sẽ hoạt động với các cuộc gọi lồng nhau, nhưng sẽ yêu cầu thêm một kiểm tra:
function resolveUnknownProps(obj, resolveKey) {
const handler = {
get(target, key) {
if (
target[key] !== null &&
typeof target[key] === 'object'
) {
return resolveUnknownProps(target[key], resolveKey);
} else if (!target[key]) {
return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
}
return target[key];
},
};
return new Proxy(obj, handler);
}
const user = {}
console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }
vì vậy bạn sẽ sử dụng nó như sau:
const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
if (!isUndefined) {
// do someting
}