Kiểm tra nếu một khóa tồn tại trong một đối tượng JavaScript?


2970

Làm cách nào để kiểm tra xem một khóa cụ thể có tồn tại trong một đố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ó có trả về sai không? Hoặc ném một lỗi?


2
Mọi thứ (hầu hết 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

một cách giải quyết nhanh, thường là tôi đi property.key = property.key || 'some default value', chỉ trong trường hợp tôi muốn khóa đó tồn tại với một số giá trị của nó
RGLSV

Câu trả lời:


4119

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

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

Thay vào đó, bạn nên sử dụng intoán tử:

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

Nếu bạn muốn kiểm tra xem 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 kiểm tra đặc biệt các thuộc tính của thể hiện đối tượng (và không 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 pháp mà là in, hasOwnPropertyvà quan trọng là undefined, hãy xem điểm chuẩn


83
Có một tài sản với giá trị được xác định thủ công không xác định hoàn toàn không có ý nghĩa. Nó sẽ là một oxymoron thực sự.
joebert

259
Tôi tin rằng có những trường hợp sử dụng để có các thuộc tính cố ý được đặt thành không xác định.
Ates Goral

168
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 đặt thành không xác định (cho đến khi hàm băm thay đổi). Để 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 ta phải sử dụng window.hasOwnProperty ("onhashchange");
Samoody

7
Một vấn đề tương tự tồn tại trong PHP khi null == nonexistent: stackoverflow.com/q/418066/372654 và thật không may, null cũng có sử dụng ở đó.
Halil zgür

80
@joebert Chỉ vì điều gì đó 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ó nhiều thư viện làm những việc vô nghĩa.
Crashworks

298

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 một đố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ề sai? 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 mảng (kết hợp) hoặc kiểu đối tượng sẽ trả về một hằng số không xác định .

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

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 trong toán tử để biết khóa có thực sự ở đó không. Nhưng, nhưng với 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ế Mô tả thuộc tính trong Javascript (tương tự như phản chiếu Java trong ngôn ngữ Java).

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

Loại Mô tả thuộc tính được sử dụng để giải thích thao tác và thống nhất các thuộc tính thuộc tính được đặt tên. Các 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à một tên thuộc tính và giá trị của nó là một giá trị thuộc tính tương ứng như được chỉ định trong 8.6.1. Ngoài ra, bất kỳ lĩnh vực 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

So sánh truy cập khóa trong JS.

Sử dụng trong toán tử
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 các yếu tố trực tiếp (kiểu ngoặc)
var result = array["Impression"] === undefined

Kết quả là

168,270,439 ±0.13 ops/sec     0.02% slower 
Truy cập các yếu tố trực tiếp (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 undefinedgiá trị là gì?

Câu hỏi đó đánh đố tôi. Trong Javascript, có ít nhất hai tài liệu tham khảo cho các đối tượng vắng mặt để tránh các vấn đề như thế này: nullundefined.

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

Đối chiếu:

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 có undefinedgiá 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 giá trị tài sản. Nếu không, sử dụng intoán tử hoặc hasOwnProperty()phương thức chậm .

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

Như mọi người đã nhận xét, các phiên bản hiện đại của công cụ Javascript (ngoại trừ firefox) đã thay đổi cách tiếp cận đối với 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ước đó đối với trường hợp cụ thể nà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.


1
Có phải tất cả các phương thức này đều được chấp nhận trong tất cả các trình duyệt được sử dụng phổ biến, ví dụ IE8 +?
Justin

11
+1 cho điểm chuẩn. Cảm ơn bạn, đây chính xác là thông tin tôi đã hy vọng tìm thấy. Chắc chắn là một đối số mạnh để viết mã không bao giờ gán hoặc mong đợi một khóa chứa giá trị không xác định .
TJ Compton

Tôi tò mò về cách so sánh của Underscore.js, vì vậy tôi đã thêm nó vào jsperf ( phiên bản 11 ). Hóa ra nó thuộc nhóm chậm cùng với in và hasOwnProperty ().
mpoisot 10/03/2015

3
Một lý do tôi sẽ thiết lập undefined đến một giá trị băm là tôi thực sự muốn xóa chính tài sản từ băm, nhưng delete hash[key]chậm hơn nhiều so với hash[key] = undefined . Tất nhiên trong trường hợp này, thật vô nghĩa khi tôi cần người invận hành, nhưng nó hoạt động như một ví dụ mẫu cho chúng ta nên luôn luôn tránh đặt giá trị thành không xác định được.
Alan Tam

1
Như @ HüseyinYağlı đã đề cập, nếu bạn kiểm tra liên kết jsperf , hiệu suất đã thay đổi đáng kể giữa các phương thức khác nhau cho hầu hết các trình duyệt do câu trả lời này ban đầu được viết. Firefox là một trong số ít vẫn có lợi thế đáng kể khi 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

144

Nó sẽ trở lại undefined.

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

undefinedlà 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 lý do tại sao tôi muốn, nhưng chỉ vì mục đích hoàn chỉnh, bạn có thể sử dụng intoán tử

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

8
Điều gì xảy ra nếu khóa tồn tại nhưng giá trị thực sự không được xác định?
Ates Goral

13
Bạn nên sử dụng === thay vì == khi so sánh với không xác định, nếu không null sẽ so sánh bằng với không xác định.
Matthew Crumley

10
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 nên được thực hiện) không xác định không phải là một giá trị hằng số đặc biệt. Trên thực tế, đó không phải là một từ khóa dành riêng và bạn có thể ghi đè lên nó, ví dụ như vậy var undefined = 42;. Khi kiểm tra các đạo cụ không xác định, bạn nên luôn luôn sử dụng ((typeof variable) === "undefined").
ssice

1
@ssice undefinedkhông phải là một tài sản có thể ghi theo spec ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
therealrootuser

1
Trong các phiên bản trước của JavaScript, 'không xác định' và 'NaN' là các biến có thể thay đổi có thể được xác định 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

32

Các câu trả lời được chấp nhận đề cập đến đối tượng . Cẩn thận khi sử dụng intoán tử trên Array để tìm dữ liệu thay vì các 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 mảng: Cách tốt nhất để tìm xem một mục có nằm trong mảng JavaScript không?


Điểm tốt, cảm ơn bạn. :)
Lucas Sousa

29
"key" in obj

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


Mã này cũng sẽ cung cấp đúng cho một khóa được xác định trên nguyên mẫu Class: function A () {}; A.prototype.b = 2; var a = new A (); Thì 'b' trong a là đúng. Trong khi a.hasOwnProperty ('b') tất nhiên là sai.
Alexander

24

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

  1. !!obj.theProperty
    Sẽ chuyển đổi giá trị thành bool. trả về truecho tất cả trừ falsegiá trị
  2. ' theProperty' trong obj
    Sẽ trả lại đúng nếu tài sản 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ó toStringphương thức, 1 và 2 sẽ trả về true trên đó, trong khi 3 có thể trả về false trên đó.)

Tài liệu tham khảo:

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


!! obj.theProperty thất bại khi giá trị không được xác định. Vd:var a = {a : undefined, b : null}; !!a.a **will return false**
ARJUN

từ đánh giá: !!obj.thePropertykhông phải là một giải pháp để kiểm tra xem một đối tượng có thuộc tính được đặt tên hay không theProperty. Nó không thành công cho bất kỳ giá trị thuộc tính falsey nào undefined, null, số 0hoặc NaNchuỗi rỗng""
traktor53

15

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

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

yourArray = {age: "10"}

_.has(yourArray, "age")

trả về đúng

Nhưng,

_.has(yourArray, "invalidKey")

trả về sai


15

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 innhà điều hành sẽ kiểm tra xem phím tồn tại trong đối tượ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 sự cố vì một khóa có thể tồn tại trong đối tượng của bạn với undefinedgiá trị.

Vì lý do đó, trước tiên nên sử dụng intoán tử tốt hơn nhiều và sau đó so sánh giá trị bên trong khóa một khi bạn đã biết nó tồn tại.


12

Đây là một chức năng 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 truyền cho nó 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.

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

// How to use it:
// Searching for keys in Arrays
console.log(keyExists('apple', ['apple', 'banana', 'orange'])); // true
console.log(keyExists('fruit', ['apple', 'banana', 'orange'])); // false

// Searching for keys in Objects
console.log(keyExists('age', {'name': 'Bill', 'age': 29 })); // true
console.log(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.


6
Điều này có vẻ hơi khó hiểu: trước tiên, khi tìm kiếm một mảng, phương thức này đang kiểm tra một giá trị , không phải là 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 Array.indexOfphương thức tích hợp? (nếu bạn đang tìm kiếm một giá trị, đó là)
Nick F

9

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Nếu bạn muốn kiểm tra xem đối tượng có ít nhất một thuộc tính trong es2015 không

Object.keys(yourObjName).length : true ? false

7

Giải pháp ES6

sử dụng Array#someObject.keys. Nó sẽ trả về true nếu khóa đã cho tồn tại trong đối tượng hoặc false nếu không.

var obj = {foo: 'one', bar: 'two'};
    
function isKeyInObject(obj, key) {
    var res = Object.keys(obj).some(v => v == key);
    console.log(res);
}

isKeyInObject(obj, 'foo');
isKeyInObject(obj, 'something');

Ví dụ một dòng.

console.log(Object.keys({foo: 'one', bar: 'two'}).some(v => v == 'foo'));


1
Nó sẽ thất bại cho các thuộc tính không đếm được của đối tượng.
Sid

@Sid Cho tôi vài ví dụ.
loại người dùng

Bạn đi đây hãy để joshua = {name: 'Joshua', địa chỉ: 'London'}; Object.defineProperty (joshua, 'isMarried', {value: true, liệt kê: false}); console.log ('isMarried' trong Object.keys (joshua))
Sid

Tôi đang áp dụng giải pháp của bạn trên đối tượng của tôi. Nó không nên được đưa ra đúng cho đầu ra đầu tiên? console.log (Object.keys (joshua) .some (v => v == 'isMarried')); console.log (joshua.isMarried);
Sid

1
Tôi xin lỗi nhưng bạn đã kiểm tra đầu ra của câu lệnh console thứ hai chưa? Object.defineProperty tương đương với việc đặt thuộc tính bằng cách sử dụng ký hiệu dấu chấm.
Sid

6

Chúng ta có thể sử dụng - hasOwnProperty.call(obj, key);

Cách undererscore.js -

if(_.has(this.options, 'login')){
  //key 'login' exists in this.options 
}

_.has = function(obj, key) {
  return hasOwnProperty.call(obj, key);
};

5

Cách dễ nhất để kiểm tra là

"key" in object

ví dụ:

var obj = {
  a: 1,
  b: 2,
}
"a" in obj // true
"c" in obj // false

Trả về giá trị như đúng ngụ ý rằng khóa tồn tại trong đối tượng.


4

Đối với những người đã lodashbao gồm trong dự án của họ:
Có một phương thức _.get lodash cố gắng lấy các khóa "sâu":

Nhận giá trị tại đường dẫn của đối tượng. Nếu giá trị được giải quyết không được xác định, defaultValue được trả về vị trí của nó.

var object = { 'a': [{ 'b': { 'c': 3 } }] };

console.log(
  _.get(object, 'a[0].b.c'),           // => 3
  _.get(object, ['a', '0', 'b', 'c']), // => 3
  _.get(object, 'a.b.c'),              // => undefined 
  _.get(object, 'a.b.c', 'default')    // => 'default'
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>


Điều này sẽ kiểm tra một cách hiệu quả nếu khóa đó, tuy nhiên sâu , được xác định và sẽ không gây ra lỗi có thể gây hại cho dòng chương trình của bạn nếu khóa đó không được xác định.


4

Mặc dù điều này không nhất thiết phải kiểm tra nếu một khóa tồn tại, nhưng nó kiểm tra tính trung thực của một giá trị. Mà undefinednullthuộc về.

Boolean(obj.foo)

Giải pháp này hoạt động tốt nhất đối với tôi vì tôi sử dụng bản thảo và sử dụng các chuỗi như vậy 'foo' in objhoặc obj.hasOwnProperty('foo') để kiểm tra xem một khóa có tồn tại hay không không cung cấp cho tôi intellisense.


3

Nếu bạn muốn kiểm tra bất kỳ khóa nào ở bất kỳ độ sâu nào trên một đối tượng và tài khoản cho các giá trị falsey, hãy xem xét dòng này cho một hàm tiện ích:

var keyExistsOn = (o, k) => k.split(".").reduce((a, c) => a.hasOwnProperty(c) ? a[c] || 1 : false, Object.assign({}, o)) === false ? false : true;

Các kết quả

var obj = {
    test: "",
    locals: {
        test: "",
        test2: false,
        test3: NaN,
        test4: 0,
        test5: undefined,
        auth: {
            user: "hw"
        }
    }
}

keyExistsOn(obj, "")
> false
keyExistsOn(obj, "locals.test")
> true
keyExistsOn(obj, "locals.test2")
> true
keyExistsOn(obj, "locals.test3")
> true
keyExistsOn(obj, "locals.test4")
> true
keyExistsOn(obj, "locals.test5")
> true
keyExistsOn(obj, "sdsdf")
false
keyExistsOn(obj, "sdsdf.rtsd")
false
keyExistsOn(obj, "sdsdf.234d")
false
keyExistsOn(obj, "2134.sdsdf.234d")
false
keyExistsOn(obj, "locals")
true
keyExistsOn(obj, "locals.")
false
keyExistsOn(obj, "locals.auth")
true
keyExistsOn(obj, "locals.autht")
false
keyExistsOn(obj, "locals.auth.")
false
keyExistsOn(obj, "locals.auth.user")
true
keyExistsOn(obj, "locals.auth.userr")
false
keyExistsOn(obj, "locals.auth.user.")
false
keyExistsOn(obj, "locals.auth.user")
true

Đồng thời xem gói NPM này: https://www.npmjs.com/package/has-deep-value


3
const object1 = {
  a: 'something',
  b: 'something',
  c: 'something'
};

const key = 's';

// Object.keys(object1) will return array of the object keys ['a', 'b', 'c']

Object.keys(object1).indexOf(key) === -1 ? 'the key is not there' : 'yep the key is exist';

3

Trong thế giới 'mảng', chúng ta có thể xem các chỉ mục như một số loại khóa. Điều đáng ngạc nhiên là intoán tử (là lựa chọn tốt cho đối tượng) cũng hoạt động với mảng. Giá trị trả về cho khóa không tồn tại làundefined

let arr = ["a","b","c"]; // we have indexes: 0,1,2
delete arr[1];           // set 'empty' at index 1
arr.pop();               // remove last item

console.log(0 in arr,  arr[0]);
console.log(1 in arr,  arr[1]);
console.log(2 in arr,  arr[2]);


2

yourArray.indexOf (yourArrayKeyName)> -1

fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple') > -1

thật


fruit = ['apple', 'grapes', 'banana']

fruit.indexOf('apple1') > -1

sai


0

Những ví dụ này có thể chứng minh sự khác biệt giữa các cách khác nhau. Hy vọng nó sẽ giúp bạn chọn đúng cho nhu cầu của bạn:

// Lets create object `a` using create function `A`
function A(){};
A.prototype.onProtDef=2;
A.prototype.onProtUndef=undefined;
var a=new A();
a.ownProp = 3;
a.ownPropUndef = undefined;

// Let's try different methods:

a.onProtDef; // 2
a.onProtUndef; // undefined
a.ownProp; // 3
a.ownPropUndef; // undefined
a.whatEver; // undefined
a.valueOf; // ƒ valueOf() { [native code] }

a.hasOwnProperty('onProtDef'); // false
a.hasOwnProperty('onProtUndef'); // false
a.hasOwnProperty('ownProp'); // true
a.hasOwnProperty('ownPropUndef'); // true
a.hasOwnProperty('whatEver'); // false
a.hasOwnProperty('valueOf'); // false

'onProtDef' in a; // true
'onProtUndef' in a; // true
'ownProp' in a; // true
'ownPropUndef' in a; // true
'whatEver' in a; // false
'valueOf' in a; // true (on the prototype chain - Object.valueOf)

Object.keys(a); // ["ownProp", "ownPropUndef"]

-1

Giải pháp tuyệt vời mới với Cấu trúc JavaScript :

let obj = {
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
};

let {key1, key2, key3, key4} = obj;

// key1 = "value1"
// key2 = "value2"
// key3 = "value3"
// key4 = undefined

// Can easily use `if` here on key4
if(!key4) { console.log("key not present"); } // Key not present

Kiểm tra việc sử dụng JavaScript khác

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.