Phát hiện một thuộc tính đối tượng không xác định


Câu trả lời:


2680

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ề undefinedtheo 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 === undefinedcó 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 undefinedgiá trị đặc biệt :

if(myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}

9
nếu một cái gì đó là null thì nó được định nghĩa (là null), nhưng bạn có thể kết hợp các kiểm tra quá. Chi tiết khó chịu của đoạn mã trên là bạn không thể xác định hàm để kiểm tra, bạn cũng có thể xác định hàm ... nhưng hãy thử sử dụng nó.
neu-rah

5
@ neu-rah tại sao bạn không thể viết một hàm? Tại sao một cái gì đó như thế này làm việc? Nó dường như làm việc cho tôi. Có một trường hợp tôi không xem xét? jsfiddle.net/djH9N/6
Zack

7
@Zack Các bài kiểm tra của bạn cho isNullorUnd xác định không xem xét trường hợp bạn gọi isNullOrUnd xác định (f) và f không được khai báo (nghĩa là không có khai báo "var f").
pnkfelix

109
Blah, hàng ngàn phiếu bầu bây giờ. Đây là cách tồi tệ nhất có thể để làm điều đó. Tôi hy vọng những người qua đường xem bình luận này và quyết định kiểm tra các câu trả lời khác .
Ry-

17
Bạn chỉ có thể sử dụng obj !== undefinedngay bây giờ. undefinedđã từng là đột biến, giống như undefined = 1234nhữ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
Bruno Buccolo 15/03/2016

899

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ó.

Mã chính xác

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 myVarkhông được khai báo.

Mã thoái hóa. KHÔNG ĐƯỢC DÙNG.

var undefined = false;  // Shockingly, this is completely legal!
if (myVar === undefined) {
    alert("You have been misled. Run away!");
}

Ngoài ra, myVar === undefinedsẽ phát sinh lỗi trong trường hợp myVar không được khai báo.


133
+1 khi lưu ý rằng myVar === không xác định sẽ phát sinh lỗi nếu myVar không được khai báo
Enrique

73
Tôi tìm thấy lời biện minh đầu tiên được đưa ra ở đây vì không sử dụng sự === undefinedhoang 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 falsevà trong Python bạn có thể gán cho TrueFalse, 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 undefinedthậm chí đáng xem xét ở đây?
Mark Amery

19
ngoài các bình luận của Marks, tôi không nhận được điều này: "myVar === không xác định sẽ gây ra lỗi trong trường hợp myVar không được khai báo." - tại sao điều này là xấu? Tại sao tôi không muốn có lỗi nếu tôi tham chiếu các biến không được khai báo?
eis

5
Ngoài ra, hãy nhớ rằng bạn luôn có thể làm 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 0này không đặc biệt, bạn có thể đặt bất kỳ biểu thức nào ở đó.
Claudiu

28
Trong các trình duyệt hiện đại (FF4 +, IE9 +, Chrome không xác định), không thể sửa đổi undefinednữa. MDN: không xác định
user247702

228

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ị undefinedvà 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à typeofsẽ 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), typeoflà 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 undefinedvà luôn nằm trong phạm vi.

  • Điều đó undefinedcó thể được ghi đè. Có nhiều hơn thế này. undefinedkhô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ỉ đọckhông thể định cấu hình . Không có trình duyệt hiện đại nào sẽ cho phép undefinedthay đổ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 undefinedhành vi của nó - nó chỉ đưa ra những tuyên bố như undefined = 5khô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 undefinedvà 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ế undefinedbằng void 0- không dùng đến typeof. ( voidluô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 typeofcho 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 - typeofchỉ 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') {
    
}

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ị undefinedkhi đọ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ị undefinedhoặc xuất hiện trên một trong những đối tượng không có undefinedgiá trị. 'key' in objsẽ 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 undefinedtài sản của đối tượng toàn cầu. thay thế void 0khác.


@BenjaminGruenbaum Đúng nhưng hoàn toàn sai lệch. Bất kỳ bối cảnh không mặc định nào cũng có thể định nghĩa riêng 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ó.
blgt

23
@blgt Điều đó hoang tưởng và không liên quan cho bất cứ điều gì thiết thực. Mọi ngữ cảnh đều có thể ghi đè lên console.log, xác định lại các phương thức nguyên mẫu của Array và thậm chí ghi đè hook của Function.prototype.call` và thay đổi mỗi khi bạn gọi một hàm trong JavaScript. Bảo vệ chống lại điều này là rất hoang tưởng và khá ngớ ngẩn. Giống như tôi (và minitech) đã nói, bạn có thể sử dụng 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.
Benjamin Gruenbaum

19
Tôi ước tôi có nhiều hơn một upvote để cung cấp. Đây là câu trả lời đúng nhất. Tôi thực sự muốn ngừng nhìn thấy typeof something === "undefined") trong mã.
Simon Baumgardt-Wellander

@BenjaminGruenbaum Đối với các lập trình viên lười biếng, void 0là (một lần) vừa ngắn hơn an toàn hơn! Đó là một chiến thắng trong cuốn sách của tôi.
wizzwizz4

4
Đây thực sự nên là câu trả lời được chấp nhận. Đó là kỹ lưỡng nhất và cập nhật.
Patrick Michaelsen

161

Trong JavaScript có null và không xác định . Chúng có ý nghĩa khác nhau.

  • không xác định có nghĩa là giá trị biến chưa được xác định; không biết giá trị là gì
  • null có nghĩa là giá trị biến được xác định và được đặt thành null (không có giá trị).

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

42
if (
Something

59
Cần chỉ ra rằng điều này không hoàn toàn an toàn. undefinedchỉ 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 typeoflà 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.
Gabe Moothart

7
nếu một cái gì đó là một biến toàn cục không xác định, (cái gì đó == không xác định) sẽ xuất hiện lỗi javascript.
Morgan Cheng

8
Vấn đề với điều này là nếu var a = null thì a == không xác định sẽ đánh giá là đúng, mặc dù a được xác định chắc chắn nhất.
Andrew

6
Giải thích về nhận xét "Eloquent Javascript" là lạc hậu . Nếu bạn thực sự chỉ muốn kiểm tra không xác định, mã được đề xuất sẽ không hoạt động (nó cũng sẽ phát hiện điều kiện được xác định nhưng chưa có giá trị nào được xác nhận [ienull]). Mã được đề xuất "if (Something == không xác định) ..." kiểm tra cả không xác định và null (không có giá trị được đặt), nghĩa là nó được hiểu là "if ((một cái gì đó không xác định) HOẶC (một cái gì đó là null)) ..." Những gì tác giả đang nói là thường những gì bạn thực sự muốn là kiểm tra cả không xác định và null.
Chuck Kollars

125

Đ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 }

o.akhông xác định? Đúng! Giá trị của nó là không xác định. Là o.bkhô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'obj.prop === undefinedtương đương, và chúng không phân biệt các tình huống khác nhau đó. Và 'prop' in objcó 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.

Vậy lam gi?

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

Ghi chú:

  • Bạn không thể kiểm tra một đối tượng và tài sản của nó cùng một lúc. Ví dụ, cái này x.a === undefinedhoặc cái này typeof x.a == 'undefined'tăng ReferenceError: x is not definednếu x không được xác định.
  • Biến undefinedlà một biến toàn cục (vì vậy thực sự nó nằm window.undefinedtrong 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.

Trận chiến cuối cùng: obj.prop === undefinedvstypeof obj.prop == 'undefined'

Điểm cộng của obj.prop === undefined:

  • Nó ngắn hơn một chút và trông đẹp hơn một chút
  • Công cụ JavaScript sẽ báo lỗi nếu bạn viết sai chính tả 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':

  • Nó thực sự là phổ quát! Nó hoạt động trong các trình duyệt mới và cũ.

Đ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.

Cập nhật (đối với JavaScript phía máy chủ):

Node.js hỗ trợ biến toàn cục undefinedglobal.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.


@Bergi cảm ơn bạn đã bình luận của bạn. Tôi đã sửa câu trả lời của tôi. Để bảo vệ tôi có thể nói rằng hiện tại (kể từ v.0.10.18) tài liệu chính thức của Node.js không nói gì về việc undefinedlà 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 globalthể hiện điều ngược lại.
Konstantin Smolyanin

4
Nó không cần thêm tài liệu vì nó nằm trong thông số EcmaScript , cũng nói rằng đó [[Enumerable]]là sai :-)
Bergi

5
Về 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.
hlovdal

3
@hlovdal: Điều đó hoàn toàn vô nghĩa so với obj.prop === undefined.
Ry-

1
Khi chúng tôi đúng với tiêu đề câu hỏi Phát hiện một thuộc tính không xác định rõ ràng , không đúng với câu hỏi (khác và dễ hơn nhiều) trong câu đầu tiên („ kiểm tra nếu không xác định ...,), bạn trả lời 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 đó.
Frank Nocke

70

Vấn đề sôi xuống đến ba trường hợp:

  1. Đối tượng có tài sản và giá trị của nó là không undefined.
  2. Đối tượng có tài sản và giá trị của nó là undefined.
  3. Đối tượng không có tài sản.

Đ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.foothậ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 nullcá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).


10
Chào Michael. Đề nghị tuyệt vời, và tôi nghĩ rằng nó làm cho mọi thứ sạch sẽ hơn. Tuy nhiên, một Gotcha mà tôi tìm thấy là khi sử dụng! toán tử với "trong". Bạn phải nó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 đó.
Simon East

Xin lỗi Michael, nhưng điều này không chính xác, hoặc ít nhất là sai lệch, trong câu hỏi ban đầu. 'in' không phải là một cách đủ để kiểm tra xem một thuộc tính đối tượng có loại không xác định hay không. Để chứng minh, xin vui lòng xem fiddle này: jsfiddle.net/CsLKJ/4
tex

2
Hai phần mã đó làm một điều khác nhau! Xem xét và đối tượng được đưa ra bởi a = {b: undefined}; sau đó typeof a.b === typeof a.c === 'undefined'nhưng 'b' in a!('c' in a).
mgol

3
+1. OP không làm rõ liệu tài sản có tồn tại và có giá trị không xác định hay không , hoặc chính tài sản đó không được xác định (tức là không tồn tại).
RobG

Tôi sẽ đề nghị thay đổi điểm (2.) trong bảng đầu tiên của bạn thành { 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).
mucaho

46
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.


47
parens là không cần thiết vì typeof là một toán tử
aehlke

12
Nhưng họ làm cho nó rõ ràng hơn những gì đang được kiểm tra. Nếu không, nó có thể được đọc là typeof (something == "undefined").
Abhi Beckert

Nếu bạn cần dấu ngoặc đơn, thì bạn nên tìm hiểu mức độ ưu tiên của toán tử trong JS: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Ian

11
Dấu ngoặc đơn rất hữu ích vì bạn KHÔNG cần phải học ưu tiên toán tử trong JS, cũng như không cần suy đoán liệu các lập trình viên bảo trì trong tương lai có cần học ưu tiên toán tử trong JS hay không.
DaveWalley

27
Dấu ngoặc là hữu ích để làm rõ mọi thứ. Nhưng trong trường hợp này, chúng chỉ làm cho toán tử trông giống như một hàm. Không có nghi ngờ điều này làm rõ ý định của lập trình viên. Nhưng nếu bạn không chắc chắn về quyền ưu tiên của nhà điều hành, bạn nên viết nó thành (typeof something) === "undefined".
Robert

42

Tôi không chắc nguồn gốc của việc sử dụng ===với typeoftừ đâ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

Điểm tuyệt vời Eric. Có một hit hiệu suất từ ​​loại kiểm tra cũng?
Simon East

5
@Simon: hoàn toàn ngược lại - người ta có thể mong đợi hiệu suất nhẹ để tránh bị ép buộc trong trường hợp '==='. Thử nghiệm nhanh và bẩn đã cho thấy '===' nhanh hơn 5% so với '==' trong FF5.0.1
Antony Hatchkins

5
Thử nghiệm kỹ lưỡng hơn đã chỉ ra rằng trong FF, IE và Chrome '==' nhanh hơn hoặc ít hơn '===' (5-10%) và Opera hoàn toàn không tạo ra bất kỳ sự khác biệt nào: jsperf.com/triple- bằng-so-hai lần bằng / 6
Antony hatchkins

3
Việc sử dụng ==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.
Alnitak

7
==là một nhân vật ít hơn ===:)
svidgen

25

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để inkiể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

21

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.myvarlà như nhau cho myvar = undefinedhay myvar = falsehay 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)


19

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).


2
Nếu bạn muốn biết lý do tại sao điều này hoạt động: Javascript: Toán tử logic và sự thật /
giả dối

nếu bạn muốn gán thuộc tính cho một biến nếu nó được xác định, không null và không falsey, người khác sử dụng một số giá trị mặc định, bạn có thể sử dụng: var x = obj && obj.prop || 'default';
Stijn de Witt

Tôi tin rằng câu hỏi là để kiểm tra chống lại không xác định rõ ràng. Kiểm tra điều kiện của bạn chống lại tất cả các giá trị sai của JS.
NikoKyriakid

15

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;
}

3
void 0chỉ 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. :-)
RobG

2
voidlà một từ dành riêng, trong khi undefinedkhông có nghĩa là trong khi undefinedbằng với void 0mặc định, bạn có thể gán một giá trị cho undefinedví dụ undefined = 1234.
Brian M. Hunt

isUndefined(obj): 16 ký tự. obj === void 0: 14 ký tự. 'nói không hay.
Stijn de Witt

14

Đơ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 typeofgiú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 typeofmã 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 typeofnế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


13

' if (window.x) {} ' là lỗi an toàn

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.

Ví dụ: Tôi muốn biết liệu trình duyệt của tôi có hỗ trợ API Lịch sử không

if (window.history) {
    history.call_some_function();
}

Cách thức hoạt động:

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.xtrả về không xác định . không xác định dẫn đến sai khi if () đánh giá nó.


Nhưng nếu bạn chạy trong Node thì sao? typeof history != 'undefined'thực sự hoạt động trong cả hai hệ thống.
Stijn de Witt

13

Đọ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.

Không bao giờ xác định

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 truenếu nó được định nghĩa là nullhoặ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");

Được xác định là không xác định hoặc không bao giờ được xác định

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ị undefinedhoặ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");

Được xác định là giá trị giả, không xác định, null hoặc không bao giờ được xác định.

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ả undefinedhay 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");
}

4
Tôi nghĩ bạn có thể thay thế ví dụ cuối cùng bằngif (!obj.prop)
Stijn de Witt

@StijndeWitt, bạn có thể, tôi khá thiếu kinh nghiệm khi tôi viết bài này và tiếng Anh của tôi dường như cũng tệ như vậy, tuy nhiên, không có gì sai trong câu trả lời
Travis

3
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.
Patrick Roberts

@PatrickRoberts Bạn nói đúng. Khi tôi viết câu trả lời này vào tháng 2 năm 2015 (trước ES6), tùy chọn đầu tiên tôi vạch ra đã thực sự hoạt động, nhưng giờ nó đã lỗi thời.
Travis

12
"propertyName" in obj //-> true | false

10

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')


3
Nhưng nó sẽ ném ReferenceError nếu fookhông được khai báo.
daniel1426

1
@ daniel1426: Vì vậy, nếu có lỗi trong mã của bạn, bạn muốn ẩn nó thay vì sửa nó? Không phải là một cách tiếp cận tuyệt vời, IMO.

Điều này không được sử dụng để ẩn lỗi. Đó là cách phổ biến để phát hiện các thuộc tính của môi trường để xác định polyfill. Ví dụ: if (typeof Promise === 'không xác định') {/ * xác định Promise * /}
gaperton

10

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 ...


3
Để rõ rà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.
clacke

1
Sai lầm. Điều này đưa ra một lỗi nếu biến chưa được tạo. Không nên bỏ phiếu lên. Sử dụng typeof thay thế.
Simon East

10

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


Mặc dù nó sẽ không ảnh hưởng đến tính hợp lệ của mã của bạn, nhưng bạn đã có một lỗi đánh máy: getUndefiendnên như vậy getUndefined.
icktoofay

8

Đâ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 đó.


Người typeofbả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 restResultkhông được xác định hoặc không được khai báo, nó vẫn sẽ ném.

Trong trường hợp của bạn, bạn có thể đơn giản hơn kiểm tra xem mảng có trống không:if(!restResult.data.length) { throw "Some error"; }
Headbank

8

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

7

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

7

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;

jQuery cũng sẽ giải quyết mọi vấn đề tương thích giữa các trình duyệt với các API JavaScript khác nhau.
Henry Heleine

7

Nếu bạn đang sử dụng Angular:

angular.isUndefined(obj)
angular.isUndefined(obj.prop)

Underscore.js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 

2
Làm thế nào để tôi thêm 1và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ư typeofkiểm tra)
Stijn de Witt

6

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 thishoặc windowlà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 đó abclà không xác định và nó được xác định sau khi khởi tạo.


5

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);

isUnd xác định1:

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

isUnd xác định2:

Chuyển đổi giá trị đầu vào thành chuỗi để so sánh "undefined"và đảm bảo giá trị âm.

isUnd xác định3:

Trong js, tham số tùy chọn hoạt động khi giá trị đầu vào chính xác undefined.


5

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


Tôi đã từng sử dụng rất nhiều chức năng có được từ lodash, rất thuận tiện cho việc truy cập loại đối tượng này, nhưng chuỗi tùy chọn mới bao trùm hầu hết các cách sử dụng _.get
Al Hill

4
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
}

5
Không. Đừng làm điều này. Chỉ cần một bài kiểm tra rất đơn giản để chứng minh rằng bạn không thể bao bọc một typeofbà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.
Stijn de Witt

4

Tôi muốn cho bạn xem thứ gì đó tôi đang sử dụng để bảo vệ undefinedbiến:

Object.defineProperty(window, 'undefined', {});

Điều này cấm mọi người thay đổi window.undefinedgiá 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.


4

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
}
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.