Câu hỏi Kiểm tra xem một khóa có tồn tại trong đối tượng JavaScript không?


Làm cách nào để kiểm tra xem một khóa cụ thể có tồn tại trong đối tượng hoặc mảng JavaScript không?

Nếu một khóa không tồn tại, và tôi cố gắng truy cập nó, nó sẽ trả về false? Hoặc ném một lỗi?


2228
2017-07-08 13:21


gốc


Tất cả mọi thứ (gần như mọi thứ) trong JavaScript là một đối tượng hoặc có thể được tạo thành một. Đây là nơi các mảng kết hợp giả được sinh ra giống như @PatrickM đã chỉ ra. - Andrew Larsson
điểm chuẩn này jsben.ch/#/WqlIl cung cấp cho bạn tổng quan về các cách phổ biến nhất để đạt được kiểm tra này. - EscapeNetscape


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


Việc kiểm tra tính không xác định không phải là một cách chính xác để kiểm tra xem một khóa có tồn tại hay không. Điều gì xảy ra nếu khóa tồn tại nhưng giá trị thực sự undefined?

var obj = { key: undefined };
obj["key"] != undefined // false, but the key exists!

Thay vào đó, bạn nên sử dụng in nhà điều hành:

"key" in obj // true, regardless of the actual value

Nếu bạn muốn kiểm tra xem một khóa không tồn tại, hãy nhớ sử dụng dấu ngoặc đơn:

!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj   // ERROR!  Equivalent to "false in obj"

Hoặc, nếu bạn muốn đặc biệt kiểm tra các thuộc tính của cá thể đối tượng (và không phải thuộc tính kế thừa), hãy sử dụng hasOwnProperty:

obj.hasOwnProperty("key") // true

Để so sánh hiệu suất giữa các phương thức in, hasOwnProperty và chìa khóa là undefined, xem này điểm chuẩn


3087
2017-07-08 15:51



Có một tài sản với một giá trị được xác định bằng tay của undefined làm cho hoàn toàn không có ý nghĩa. Nó sẽ là một oxymoron thực sự. - joebert
Tôi tin rằng có những trường hợp sử dụng để có thuộc tính cố tình được đặt thành không xác định. - Ates Goral
Trường hợp sử dụng hợp lệ: Gecko 1.9.1 [Firefox 3.5] không có thuộc tính window.onhashchange. Gecko 1.9.2 [Firefox 3.6] có thuộc tính này được thiết lập là không xác định (cho đến khi thay đổi băm). Để tính năng phát hiện lịch sử băm hoặc phiên bản trình duyệt, người dùng phải sử dụng window.hasOwnProperty ("onhashchange"); - SamGoody
Một vấn đề tương tự tồn tại trong PHP, nơi null == không tồn tại: stackoverflow.com/q/418066/372654 và không may, null cũng có sử dụng. - Halil Özgür
@joebert Chỉ vì một cái gì đó là vô nghĩa không có nghĩa là bạn sẽ không gặp phải nó trong mã sản xuất. Có rất nhiều thư viện làm những điều vô nghĩa. - Crashworks


câu trả lời nhanh

Làm cách nào để kiểm tra xem một khóa cụ thể có tồn tại trong đối tượng hoặc mảng JavaScript không?   Nếu một khóa không tồn tại và tôi cố gắng truy cập nó, nó sẽ trả về false? Hoặc ném một lỗi?

Truy cập trực tiếp một thuộc tính bị thiếu bằng cách sử dụng kiểu kết hợp (kiểu kết hợp) hoặc kiểu đối tượng sẽ trả về một chưa xác định không thay đổi.

Chậm và đáng tin cậy trong toán tử và hasOwnProperty phương pháp

Như mọi người đã đề cập ở đây, bạn có thể có một đối tượng có thuộc tính được liên kết với hằng số "không xác định".

 var bizzareObj = {valid_key:  undefined};

Trong trường hợp đó, bạn sẽ phải sử dụng hasOwnProperty hoặc là trong điều hành để biết liệu khóa có thực sự ở đó không. Nhưng, nhưng ở mức giá nào?

vì vậy, tôi nói với bạn ...

trong toán tử và hasOwnProperty là "các phương thức" sử dụng cơ chế Trình mô tả thuộc tính trong Javascript (tương tự như sự phản chiếu Java trong ngôn ngữ Java).

http://www.ecma-international.org/ecma-262/5.1/#sec-8.10

Kiểu mô tả thuộc tính được sử dụng để giải thích thao tác và sửa đổi các thuộc tính thuộc tính được đặt tên. Giá trị của loại Mô tả thuộc tính là các bản ghi bao gồm các trường được đặt tên trong đó tên của mỗi trường là tên thuộc tính và giá trị của nó là giá trị thuộc tính tương ứng như được chỉ định trong 8.6.1. Ngoài ra, bất kỳ trường nào cũng có thể có mặt hoặc vắng mặt.

Mặt khác, gọi một phương thức hoặc khóa đối tượng sẽ sử dụng cơ chế Javascript [[Get]]. Đó là cách xa nhanh hơn!

điểm chuẩn

http://jsperf.com/checking-if-a-key-exists-in-a-javascript-array

Comparing key access in JS.

Sử dụng trong nhà điều hành
var result = "Impression" in array;

Kết quả là

12,931,832 ±0.21% ops/sec      92% slower 
Sử dụng hasOwnProperty
var result = array.hasOwnProperty("Impression")

Kết quả là

16,021,758 ±0.45% ops/sec     91% slower
Truy cập trực tiếp các phần tử (kiểu dấu ngoặc vuông)
var result = array["Impression"] === undefined

Kết quả là

168,270,439 ±0.13 ops/sec     0.02% slower 
Truy cập trực tiếp các phần tử (kiểu đối tượng)
var result = array.Impression  === undefined;

Kết quả là

168,303,172 ±0.20%     fastest

EDIT: lý do để gán cho một tài sản là gì undefined giá trị?

Câu hỏi đó giải đố tôi. Trong Javascript, có ít nhất hai tham chiếu cho các đối tượng vắng mặt để tránh các vấn đề như sau: null và undefined.

null là giá trị nguyên thủy đại diện cho sự vắng mặt cố ý của bất kỳ giá trị đối tượng nào hoặc trong ngắn hạn, đã xác nhận thiếu giá trị. Mặt khác, undefined là giá trị không xác định (không được xác định). Nếu có thuộc tính sẽ được sử dụng sau đó với đúng giá trị xem xét sử dụng null tham chiếu thay vì undefined bởi vì trong thời điểm ban đầu, tài sản là đã xác nhận thiếu giá trị.

So sánh:

var a = {1: null}; 
console.log(a[1] === undefined); // output: false. I know the value at position 1 of a[] is absent and this was by design, i.e.:  the value is defined. 
console.log(a[0] === undefined); // output: true. I cannot say anything about a[0] value. In this case, the key 0 was not in a[].

khuyên nhủ

Tránh các đối tượng với undefined giá trị. Kiểm tra trực tiếp bất cứ khi nào có thể và sử dụng null để khởi tạo các giá trị thuộc tính. Nếu không, hãy sử dụng chậm in nhà điều hành hoặc hasOwnProperty() phương pháp.

EDIT: 12/04/2018 - KHÔNG LIÊN QUAN ĐẾN BẤT KM NÀO

Như mọi người đã nhận xét, phiên bản hiện đại của các công cụ Javascript (với ngoại lệ firefox) đã thay đổi cách tiếp cận cho các thuộc tính truy cập. Việc triển khai hiện tại chậm hơn so với trường hợp cụ thể trước đây, nhưng sự khác biệt giữa khóa truy cập và đối tượng là không thể bỏ qua.


224
2018-02-27 16:38



Tất cả các phương pháp này có được chấp nhận trong tất cả các trình duyệt thường được sử dụng hay không, ví dụ: IE8 +? - Justin
@Justin Có. Nó sẽ hoạt động. Bạn có thể kiểm tra trực tiếp trên jsperf.com/checking-if-a-key-exists-in-a-javascript-array. - rdllopes
1 cho điểm chuẩn. Cảm ơn bạn, đây chính là thông tin mà tôi đã hy vọng tìm thấy. Chắc chắn là một đối số mạnh mẽ để viết mã mà không bao giờ gán hoặc mong đợi một khóa để chứa giá trị chưa xác định. - T.J. Compton
Một lý do tôi sẽ đặt không xác định thành giá trị băm là tôi thực sự muốn xóa khóa thuộc tính đó khỏi băm nhưng delete hash[key] Là chậm hơn nhiều  hash[key] = undefined. Tất nhiên trong trường hợp này nó không có ý nghĩa với tôi để cần in nhà điều hành, nhưng nó hoạt động như một counterexample để "chúng ta nên luôn luôn tránh thiết lập giá trị để không xác định". - Alan Tam
Như @ HüseyinYağlı đã đề cập, nếu bạn kiểm tra jsperf liên kết, hiệu suất đã thay đổi đáng kể giữa các phương pháp khác nhau cho hầu hết các trình duyệt vì câu trả lời này ban đầu được viết. Firefox là một trong số ít vẫn có một lợi thế đáng kể bằng cách sử dụng các phương thức mảng hoặc đối tượng, nhưng đối với nhiều trình duyệt khác, sự khác biệt là không đáng kể. - kevinmicke


Nó sẽ trở lại undefined.

var aa = {hello: "world"};
alert( aa["hello"] );      // popup box with "world"
alert( aa["goodbye"] );    // popup box with "undefined"

undefined là một giá trị không đổi đặc biệt. Vì vậy, bạn có thể nói, ví dụ:

// note the three equal signs so that null won't be equal to undefined
if( aa["goodbye"] === undefined ) {
    // do something
}

Đây có lẽ là cách tốt nhất để kiểm tra các phím bị thiếu. Tuy nhiên, như được chỉ ra trong một bình luận dưới đây, về mặt lý thuyết có thể là bạn muốn có giá trị thực tế undefined. Tôi chưa bao giờ cần phải làm điều này và không thể nghĩ ra một lý do nào đó tại sao tôi lại muốn, nhưng chỉ vì mục đích hoàn chỉnh, bạn có thể sử dụng in nhà điều hành

// this works even if you have {"goodbye": undefined}
if( "goodbye" in aa ) {
    // do something
}

114
2017-07-08 13:24



Điều gì xảy ra nếu khóa tồn tại nhưng giá trị thực sự không xác định? - Ates Goral
Bạn nên sử dụng === thay vì == khi so sánh với undefined, nếu không null sẽ so sánh bằng với undefined. - Matthew Crumley
Eli câu trả lời của bạn không hoàn toàn chính xác. Bởi vì dù sao (và tất nhiên điều này không bao giờ nên được thực hiện) undefined không phải là một giá trị không đổi đặc biệt. Trong thực tế, nó không phải là một từ khóa dành riêng và bạn có thể ghi đè nó, ví dụ, var undefined = 42;. Khi thử nghiệm cho các đạo cụ không xác định, bạn nên luôn sử dụng ((typeof variable) === "undefined"). - ssice
@ssice undefined không phải là thuộc tính có thể ghi theo thông số ecma-international.org/ecma-262/5.1/#sec-15.1.1.3 - therealrootuser
Trong các phiên bản trước của JavaScript, 'undefined' và 'NaN' là các biến có thể thay đổi có thể được định nghĩa lại hoặc gán các giá trị khác. Đây là một điều xấu. Nó đã được sửa trong ECMAScript 5. - jkdev


Các câu trả lời được chấp nhận đề cập đến Vật. Cẩn thận khi sử dụng in nhà điều hành trên Mảng để tìm dữ liệu thay vì khóa:

("true" in ["true", "false"])
// -> false (Because the keys of the above Array are actually 0 and 1)

Để kiểm tra các phần tử hiện có trong một Array: Cách tốt nhất để tìm xem một mục có nằm trong một mảng JavaScript không?


22
2017-07-01 12:45





"key" in obj

Có khả năng chỉ thử nghiệm các giá trị thuộc tính đối tượng rất khác với các khóa mảng


20
2018-04-25 15:45



Mã này cũng sẽ cung cấp cho đúng một khóa được định nghĩa trên nguyên mẫu Lớp: hàm A () {}; A.prototype.b = 2; var a = new A (); Sau đó 'b' trong một là đúng. Mặc dù a.hasOwnProperty ('b') dĩ nhiên là sai. - Alexander


Ba cách để kiểm tra xem một thuộc tính có tồn tại trong một đối tượng javascript hay không:

  1. obj.theProperty
    Sẽ chuyển đổi giá trị thành bool. trả về TRUE cho tất cả trừ giá trị 'false'
  2. 'theProperty' trong obj
    Sẽ trả về true nếu thuộc tính tồn tại, bất kể giá trị của nó (thậm chí trống)
  3. obj.hasOwnProperty ('theProperty')
    Không kiểm tra chuỗi nguyên mẫu. (vì tất cả các đối tượng đều có phương thức 'toString', 1 và 2 sẽ trả về true trên nó, trong khi 3 có thể trả về false.)

Tài liệu tham khảo:

http://book.mixu.net/node/ch5.html


20
2017-11-12 09:19





Nếu bạn đang sử dụng underscore.js thư viện sau đó các hoạt động đối tượng / mảng trở nên đơn giản.

Trong trường hợp của bạn _.has phương pháp có thể được sử dụng. Thí dụ:

yourArray = {age: "10"}

_.has(yourArray, "age")

trả về thật 

Nhưng,

_.has(yourArray, "invalidKey")

trả về sai


13
2018-05-29 19:37





Câu trả lời:

if ("key" in myObj)
{
    console.log("key exists!");
}
else
{
    console.log("key doesn't exist!");
}

Giải trình:

Các in toán tử sẽ kiểm tra xem khóa có tồn tại trong đối tượng hay không. Nếu bạn đã kiểm tra nếu giá trị không được xác định: if (myObj["key"] === 'undefined'), bạn có thể gặp vấn đề bởi vì khóa có thể tồn tại trong đối tượng của bạn với undefined giá trị.

Vì lý do đó, thực hành tốt hơn là đầu tiên sử dụng in toán tử và sau đó so sánh giá trị bên trong khóa khi bạn đã biết nó tồn tại.


10
2018-06-22 02:29





Đây là một hàm trợ giúp tôi thấy khá hữu ích

Điều này keyExists(key, search) có thể được sử dụng để dễ dàng tra cứu một khóa trong các đối tượng hoặc mảng!

Chỉ cần vượt qua nó chìa khóa bạn muốn tìm, và tìm kiếm obj (đối tượng hoặc mảng) mà bạn muốn tìm nó.

function keyExists(key, search) {
    if (!search || (search.constructor !== Array && search.constructor !== Object)) {
        return false;
    }
    for (var i = 0; i < search.length; i++) {
        if (search[i] === key) {
            return true;
        }
    }
    return key in search;
}

Làm thế nào để sử dụng nó:

Tìm kiếm khóa trong Mảng

keyExists('apple', ['apple', 'banana', 'orange']); // true
keyExists('fruit', ['apple', 'banana', 'orange']); // false

Tìm kiếm khóa trong Đối tượng

keyExists('age', {'name': 'Bill', 'age': 29 }); // true
keyExists('title', {'name': 'Jason', 'age': 29 }); // false

Nó khá đáng tin cậy và hoạt động tốt trên nhiều trình duyệt.


9
2018-03-05 12:56



Điều này có vẻ hơi bối rối: trước hết, khi tìm kiếm một mảng, phương pháp này đang kiểm tra giá trị, không phải chìa khóa. Thứ hai, tại sao lặp lại thông qua một mảng như thế này khi bạn có thể sử dụng built-in Array.indexOf phương pháp? (nếu bạn đang tìm kiếm một giá trị, đó là) - Nick F