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


Cách tốt nhất để kiểm tra xem một thuộc tính đối tượng trong JavaScript có được xác định không?


2434
2017-08-26 07:25


gốc




Các câu trả lời:


Sử dụng:

if (typeof something === "undefined") {
    alert("something is undefined");
}

Nếu một biến đối tượng có một số thuộc tính, bạn có thể sử dụng cùng một thứ như sau:

if (typeof my_obj.someproperties === "undefined"){
    console.log('the property is not available...'); // print into console
}

Kể từ ECMAScript 5, undefined không thể bị ghi đè, vì vậy my_obj === undefined cũng sẽ hoạt động, nhưng chỉ khi my_obj tồn tại. Điều này có thể hoặc có thể không được mong muốn bởi vì bạn cũng có thể sử dụng null nếu bạn cần ngữ nghĩa này (xem Sự khác nhau giữa null và undefined trong JavaScript là gì?). Đối với các thuộc tính đối tượng, nó hoạt động bất kể thuộc tính có tồn tại hay không.


2321
2018-01-06 12:27



nếu một cái gì đó là null thì nó được định nghĩa (là null), nhưng bạn có thể liên hợp các kiểm tra quá. Các chi tiết khó chịu của mã trên là bạn không thể xác định một hàm để kiểm tra nó, bạn cũng có thể định nghĩa hàm ... nhưng cố gắng sử dụng nó. - neu-rah
@ neu-rah tại sao bạn không thể viết một hàm? tại sao không phải thứ như thế này? 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
@Zack Các thử nghiệm của bạn cho isNullorUndefined không xem xét trường hợp bạn gọi isNullOrUndefined (f) và f không khai báo (tức là nơi không có khai báo "var f"). - pnkfelix
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 người qua đường sẽ thấy bình luận này và quyết định kiểm tra… ahem… khác câu trả lời. - Ry-♦
Bạn chỉ có thể sử dụng obj !== undefined hiện nay. undefined được sử dụng để có thể thay đổi, như undefined = 1234 điều 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-undefined-in-javascript - Bruno Buccolo


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 ngược với niềm tin chung, "không xác định" là không phải một từ khóa trong JavaScript và thực tế có thể có một giá trị được gán cho nó.

Mã đúng

Cách mạnh mẽ nhất để thực hiện bài kiểm tra này là:

if (typeof myVar === "undefined")

Điều này sẽ luôn trả lại kết quả chính xác và thậm chí xử lý tình huống myVar khô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 === undefined sẽ gây ra lỗi trong trường hợp myVar không được khai báo.


805
2017-08-23 18:03



1 để lưu ý rằng myVar === không xác định sẽ gây ra lỗi nếu myVar không được khai báo - Enrique
có - các QUOTES dường như là quan trọng. tôi đoán là hàm typeof trả về một chuỗi (định dạng mong đợi) - jsh
Tôi tìm thấy sự biện minh đầu tiên được đưa ra ở đây vì không sử dụng === 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 được 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à bằng 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 những ngôn ngữ đó theo cách như vậy để bảo vệ chống lại khả năng tự mì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? - Mark Amery
ngoài các nhận xét của Mark, tôi không hiểu điều này: "myVar === undefined 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 xấu? Tại sao tôi không phải muốn có một lỗi nếu tôi tham khảo các biến không khai báo? - eis
Trong các trình duyệt hiện đại (FF4 +, IE9 +, Chrome không xác định), bạn không còn có thể sửa đổi undefined. MDN: không xác định - Stijn


Trong JavaScript có vô giá trị và có chưa xác định. Họ có ý nghĩa khác nhau.

  • chưa 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ì.
  • vô giá trị có nghĩa là giá trị biến được định nghĩa và được đặt thành null (không có giá trị).

Marijn Haverbeke nói, trong cuốn sách trực tuyến miễn phí của ông "Eloquent JavaScript"(nhấn mạnh mỏ):

Cũng 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 undefined và null chủ yếu là học thuật, và thường không phải là rất thú vị. Trong các chương trình thực tế, nó thường là cần thiết để kiểm tra xem một cái gì đó 'có một giá trị'. Trong những trường hợp này, biểu thức cái gì đó == undefined 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 == undefined sẽ tạo ra true.

Vì vậy, tôi đoán cách tốt nhất để kiểm tra xem có điều gì đó không xác định sẽ là:

if (something == undefined)

Hi vọng điêu nay co ich!

Chỉnh sửa: Để trả lời chỉnh sửa của bạn, các thuộc tính đối tượng phải 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

133
2017-08-26 07:36



if (something == undefined) được viết tốt hơn như thể (something === undefined) - Sebastian Rittau
Cần phải chỉ ra rằng điều này không hoàn toàn an toàn. undefined chỉ là một biến có thể được người dùng chỉ định lại: 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) mà chưa được khai báo. - Gabe Moothart
nếu một cái gì đó là một biến toàn cầu không xác định, (cái gì đó == undefined) sẽ trả về lỗi javascript. - Morgan Cheng
Vấn đề với điều này là nếu var a = null thì a == undefined đánh giá là true, mặc dù chắc chắn là a được xác định chắc chắn nhất. - Andrew
Cách giải thích này của 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 không có giá trị nào được xác định [i.e.null]). Mã được đề xuất "if (something == undefined) ..." kiểm tra cả hai undefined và null (không có giá trị được đặt), tức là nó được hiểu là "if ((một cái gì đó không xác định) HOẶC (cái gì đó là null)) ..." Những gì tác giả nói là thường những gì bạn có thật không muốn là kiểm tra cả hai undefined và null. - Chuck Kollars


Mặc dù được nhiều câu trả lời khác đề xuất ở đây, typeof  là một lựa chọn tồi. Nó không bao giờ được sử dụng để 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 tồn tại. 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 tiềm năng cho một sự im lặng thất bại nếu bạn thực hiện một lỗi đánh máy trong tên biến hoặc trong chuỗi chữ '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², nơi không chắc chắn liệu một tên cụ thể có nằm trong phạm vi không (như kiểm tra typeof module !== 'undefined' như 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:

  • mà đọc một biến "uninitialized" (var foo) hoặc tham số (function bar(foo) { … }, được gọi là bar()) sẽ thất bại. Điều này đơn giản là không đúng - các biến không khởi tạo rõ ràng và các tham số không được cung cấp giá trị luôn trở thành undefinedvà luôn nằm trong phạm vi.

  • cái đó undefined có thể được ghi đè. Còn nhiều thứ nữa. undefined không phải là một từ khóa trong JavaScript. Thay vào đó, đó là thuộc tính trên đối tượng chung với giá trị Không xác định. Tuy nhiên, kể từ ES5, tài sản này đã được chỉ đọc và không thể định cấu hình. Không có trình duyệt hiện đại nào cho phép undefined tài sản sẽ được thay đổi và đến 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 không ảnh hưởng undefinedHành vi của họ - nó chỉ làm cho các câu như undefined = 5 không làm gì thay vì ném. Vì đây không phải là từ khóa, bạn có thể khai biến với tên undefinedvà các biến đó có thể được thay đổi, làm cho mẫu này phổ biến một lần:

    (function (undefined) {
        // …
    })()
    

    hơn nguy hiểm hơn việc sử dụng toàn cầu undefined. Nếu bạn phải tương thích với ES3, hãy thay thế undefined với void 0 - đừng dùng đến typeof. (void luôn luôn là toán tử đơn nhất đánh giá giá trị không xác định cho bất kỳ toán hạng nào.)

Với cách biến hoạt động ra khỏi con đường, đó là thời gian để giải quyết các câu hỏi thực tế: thuộc tính đối tượng. Không có lý do gì để sử dụng typeof cho các thuộc tính đối tượng. Ngoại lệ trước đây về tính năng phát hiện tính năng không áp dụng ở đây - typeof chỉ có hành vi đặc biệt trên các biến và các biểu thức tham chiếu đến các thuộc tính đối tượng không phải là các biến.

Điều này:

if (typeof foo.bar === 'undefined') {
    ⋮
}

luôn luôn chính xác tương đương đến này³:

if (foo.bar === undefined) {
    ⋮
}

và có tính đến lời khuyên ở trên, để tránh người đọc khó hiểu về lý do bạn sử dụng typeof, bởi vì nó có ý nghĩa nhất để sử dụng === để kiểm tra sự bình đẳng, bởi vì nó có thể được tái cấu trúc để kiểm tra giá trị của biến sau đó, và bởi vì nó chỉ đơn giản trông đẹp hơn, bạn nên luôn sử dụng === undefined³ cũng ở đây.

Một cái gì đó khác để xem xét khi nói đến thuộc tính đối tượng là liệu bạn có thực sự muốn kiểm tra undefined ở tất cả. 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), hiển thị trên đối tượng với giá trị undefined, có mặt trên nguyên mẫu của đối tượng với giá trị undefined, hoặc có mặt trên một trong những người không cóundefined giá trị. 'key' in obj sẽ cho bạn biết liệu khóa có ở bất kỳ đâ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. Tuy nhiên, tôi sẽ không đi vào chi tiết về câu trả lời về nguyên mẫu và sử dụng các đối tượng như các bản đồ có chuỗi, vì nó chủ yếu nhằm chống lại tất cả các lời khuyên xấu trong các câu trả lời khác, bất kể sự diễn giải có thể có của câu hỏi gốc. Đọc trên đối tượng nguyên mẫu trên MDN để biết thêm!

¹ sự lựa chọn bất thường của tên biến mẫu? đây là mã chết thực sự từ phần mở rộng NoScript cho Firefox.
² Tuy nhiên, đừng giả sử rằng không biết điều gì trong phạm vi nói chung là ổn. lỗ hổng thưởng do lạm dụng phạm vi động: Project Zero 1225
³ một lần nữa giả sử một môi trường ES5 + và undefined đề cập đến undefined tài sản của đối tượng toàn cục. thay thế void 0 nếu không thì.


132
2018-02-26 21:17



@BenjaminGruenbaum Đúng nhưng hoàn toàn gây hiểu nhầm. Bất kỳ ngữ cảnh không mặc định nào cũng có thể tự định nghĩa undefined, ẩn phần 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 đè nó. - blgt
@blgt Đó là hoang tưởng và không thích hợp cho bất kỳ điều gì thực tế. Mỗi ngữ cảnh có thể ghi đè console.log, xác định lại các phương thức nguyên mẫu Array và thậm chí ghi đè hàm 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. 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à ngớ ngẩn và quá mức cần thiết. - Benjamin Gruenbaum
Tôi ước gì tôi có nhiều hơn một ưu tiên để đưa ra. Đâ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 0 là (cho một lần) cả hai 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. - wizzwizz4


Điều đó có nghĩa là gì: "thuộc tính đối tượng không xác định"?

Trên thực tế nó có thể có nghĩa là hai điều khá khác nhau! Đầu tiên, nó có thể có nghĩa là tài sản 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.a chưa xác định? Vâng! Giá trị của nó là không xác định. Là o.b chưa xác định? Chắc chắn rồi! Không có tài sản 'b' ở tất cả! OK, hãy xem các cách tiếp cận khác nhau hoạt động như thế nào 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õ rằng 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 thuộc tính chưa được xác định và không chú ý đến giá trị tài sản có thể không xác định.

Vậy lam gi?

1) Bạn muốn biết nếu một tài sản là không xác định bởi một trong hai ý nghĩa đầu tiên hoặc thứ hai (tình hình điển hình nhất).

obj.prop === undefined // IMHO, see "final fight" below

2) Bạn muốn chỉ biết nếu đối tượng có một số tài sản và không quan tâm về giá trị của nó.

'prop' in obj

Ghi chú:

  • Bạn không thể kiểm tra một đối tượng và thuộc tính của nó cùng một lúc. Ví dụ, điều này x.a === undefined hay cái này typeof x.a == 'undefined' tăng giá ReferenceError: x is not defined nếu x không được xác định.
  • Biến undefined là một biến toàn cầu (thực ra nó là window.undefined trong trình duyệt). Nó đã được hỗ trợ từ ECMAScript 1st Edition và kể từ ECMAScript 5 nó là chỉ đọc. Vì vậy, trong các trình duyệt hiện đại, nó không thể định nghĩa lại thành true như nhiều tác giả thích làm chúng tôi sợ, nhưng điều này vẫn đúng với các trình duyệt cũ hơn.

Cuộc chiến cuối cùng: obj.prop === undefined so với typeof 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ẽ cung cấp cho bạn một lỗi nếu bạn viết sai chính tả undefined

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

Minuses của typeof obj.prop == 'undefined':

  • 'undefned' (sai chính tả) ở đây chỉ là một chuỗi liên tục, do đó, 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ầu undefined như global.undefined (nó cũng có thể được sử dụng mà không cần tiền tố 'chung'). Tôi không biết về các triển khai khác của JavaScript phía máy chủ.


101
2017-08-08 20:28



@Bergi cảm ơn bạn đã bình luận của bạn. Tôi đã sửa chữa câu trả lời của mình. Trong phòng thủ của tôi, tôi có thể nói rằng hiện tại (như của v.10.10.18) tài liệu chính thức của Node.js không nói gì về undefined là thành viên của global. Cũng không phải console.log(global); cũng không for (var key in global) { ... } không hiển thị chưa xác định là thành viên của toàn cầu. Nhưng thử nghiệm như 'undefined' in global cho thấy điều ngược lại. - Konstantin Smolyanin
Nó không cần thêm tài liệu kể từ nó nằm trong thông số EcmaScript, cũng nói rằng [[Enumerable]] là sai :-) - Bergi
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
@hlovdal: Điều đó hoàn toàn vô nghĩa so với obj.prop === undefined. - Ry-♦
Khi chúng ta đúng với dòng tiêu đề câu hỏi „Phát hiện một tài sản không xác định “, không đúng với câu hỏi (khác và dễ dàng hơn) trong câu đầu tiên („check if undefined ...“), bạn trả lời if ('foo' in o) ... câu trả lời của bạn thực sự là 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


Vấn đề này liên quan đến ba trường hợp:

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

Điều này cho chúng ta biết điều tôi quan tâm:

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 không vui typeof obj.foo không cho chúng tôi biết trong ba trường hợp chúng tôi 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 xét nghiệm này giống nhau đối với null mục nhập 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 nó có ý nghĩa hơn (và rõ ràng hơn) để kiểm tra xem tài sản có ở đó không, kiểm tra xem nó có được xác định hay không, và trường hợp duy nhất mà séc này sẽ khác nhau là trường hợp 2, trường hợp hiếm hoi của một mục nhập thực tế trong đối tượng có giá trị không xác định.

Ví dụ: Tôi vừa mới tái cấu trúc một loạt mã có một loạt các kiểm tra xem một đối tượng có một thuộc tính đã cho hay không.

if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

Đó là rõ ràng hơn khi viết mà không có một kiểm tra cho undefined.

if( "x" in blob ) { fn(blob.x); }

Nhưng như đã được đề cập, đây không phải là chính xác như nhau (nhưng là tốt hơn đủ cho nhu cầu của tôi).


59
2018-06-08 04:04



Chào Michael. Đề nghị tuyệt vời, và tôi nghĩ rằng nó làm cho mọi thứ sạch hơn. Tuy nhiên, một trong những thứ mà tôi đã tìm thấy là khi sử dụng! toán tử với "in". Bạn phải nói if (!("x" in blob)) {} với dấu ngoặc xung quanh trong, bởi vì! toán tử được ưu tiên hơn 'in'. Hy vọng rằng sẽ giúp một ai đó. - Simon East
Xin lỗi Michael, nhưng điều này là không chính xác, hoặc ít nhất là gây hiểu lầm, trong ánh sáng của câu hỏi ban đầu. 'in' không phải là một cách đầy đủ để kiểm tra xem một thuộc tính đối tượng có typeof chưa được xác định hay không. Đối với bằng chứng, xin vui lòng xem fiddle này: jsfiddle.net/CsLKJ/4 - Tex
Hai phần mã đó làm một việc khác! 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 và !('c' in a). - mgol
+1. OP không làm rõ liệu tài sản tồn tại và có giá trị hay không chưa xác địnhhoặc liệu thuộc tính có được xác định không (nghĩa 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 thêm nó như là một thay thế cho (2.) trong bảng - Tôi đã phải suy nghĩ một lúc để nhận ra rằng điểm (2.) đánh giá để undefined(mặc dù bạn đề cập đến sau này). - mucaho


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.


38
2017-07-27 16:03



parens là không cần thiết vì typeof là toán tử - aehlke
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 các dấu ngoặc đơn, thì bạn nên học toán tử ưu tiên trong JS: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - Ian
Dấu ngoặc đơn là hữu ích chính xác bởi vì bạn KHÔNG cần phải học toán tử ưu tiên trong JS, cũng như bạn không cần phải suy đoán liệu các lập trình viên bảo trì trong tương lai có cần phải học toán tử ưu tiên trong JS hay không. - DaveWalley
Dấu ngoặc đơn rất hữu ích để làm rõ mọi thứ. Nhưng trong trường hợp này, họ chỉ làm cho toán tử trông giống như một hàm. Không 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 về quyền ưu tiên của toán tử, bạn nên viết nó như (typeof something) === "undefined". - Robert


Tôi không chắc nguồn gốc của việc sử dụng === với typeof đến từ, 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 ta biết rằng trước, vậy tại sao bạn cũng muốn đánh dấu nó?

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

33
2017-09-22 14:20



Điểm tuyệt vời Eric. Có một hiệu suất hit từ kiểm tra loại cũng? - Simon East
@ Simon: hoàn toàn ngược lại - người ta có thể mong đợi hiệu suất nhỏ bị ảnh hưởng từ việc tránh bị ép buộc trong trường hợp '==='. Kiểm tra nhanh và bẩn đã cho thấy '===' nhanh hơn 5% so với '==' trong FF5.0.1 - Antony Hatchkins
Kiểm tra kỹ lưỡng hơn đã chỉ ra rằng dưới FF, IE và Chrome '==' nhanh hơn hoặc nhiều hơn '===' (5-10%) và Opera không tạo ra bất kỳ sự khác biệt nào cả: jsperf.com/triple-equals-vs-twice-equals/6 - Antony Hatchkins
Sử dụng == vẫn yêu cầu ít nhấ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 tiên. - Alnitak
== là một nhân vật ít hơn === :) - svidgen


Crossposting của tôi câu trả lời từ câu hỏi liên quan Làm cách nào để kiểm tra "không xác định" trong JavaScript?

Cụ thể cho câu hỏi này, xem các trường hợp thử nghiệm với someObject.<whatever>.


Một số kịch bản 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 cho in kiểm tra tạo sự khác biệt khi trong một wrapper 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

19
2018-01-13 17:43





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, bởi vì myvar không được định nghĩa, 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ó một phạm vi toàn cục (đối tượng mặc định) bên ngoài một hàm, một khai báo sẽ được 'gắn' vào đối tượng cửa sổ.

Ví dụ:

var myvar = 'test';

Biến toàn cục myvar giống như window.myvar hoặc là cửa sổ ['myvar']

Để tránh các lỗi cần kiểm tra khi biến toàn cầu tồn tại, 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 quan trọng, giá trị của nó là không chính xác. Nếu không, nó là ngớ ngẩn để khởi tạo các biến với undefined, 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 có thể chỉ cần kiểm tra kiểu của nó hoặc dựa vào !window.myvar để kiểm tra xem nó có giá trị thích hợp / hợp lệ hay không. Vì vậy, ngay cả khi biến không được xác định thì !window.myvar là như nhau cho myvar = undefined hoặc là myvar = false hoặc là myvar = 0.

Khi bạn mong đợi một loại cụ thể, hãy kiểm tra loại biến. Để tăng tốc độ kiểm tra một điều kiệ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, thông dịch viên sẽ bỏ qua các bài kiểm tra tiếp theo.

Nó luôn luôn là tốt hơn để sử dụng dụ / đối tượng của biến để kiểm tra xem nó có một 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)


14
2017-08-12 14:40