簡體   English   中英

檢查 JavaScript 對象中是否存在鍵?

[英]Checking if a key exists in a JavaScript object?

如何檢查 JavaScript 對象或數組中是否存在特定鍵?

如果密鑰不存在,而我嘗試訪問它,它會返回 false 嗎? 還是拋出錯誤?

檢查 undefined-ness 不是測試密鑰是否存在的准確方法。 如果鍵存在但值實際上undefined怎么辦?

 var obj = { key: undefined }; console.log(obj["key"] !== undefined); // false, but the key exists!

您應該改用in運算符:

 var obj = { key: undefined }; console.log("key" in obj); // true, regardless of the actual value

如果要檢查鍵是否不存在,請記住使用括號:

 var obj = { not_key: undefined }; console.log(!("key" in obj)); // true if "key" doesn't exist in object console.log(!"key" in obj); // Do not do this! It is equivalent to "false in obj"

或者,如果您想特別測試對象實例的屬性(而不是繼承的屬性),請使用hasOwnProperty

 var obj = { key: undefined }; console.log(obj.hasOwnProperty("key")); // true

對於那些方法之間的性能對比inhasOwnProperty和關鍵是undefined ,看到這個基准測試

基准測試結果

快速回答

如何檢查 JavaScript 對象或數組中是否存在特定鍵? 如果密鑰不存在而我嘗試訪問它,它會返回 false 嗎? 還是拋出錯誤?

使用(關聯)數組樣式或對象樣式直接訪問缺少的屬性將返回未定義的常量。

慢而可靠運營商和hasOwnProperty方法

正如人們在這里已經提到的那樣,您可以擁有一個具有與“未定義”常量關聯的屬性的對象。

 var bizzareObj = {valid_key:  undefined};

在這種情況下,您將不得不使用hasOwnPropertyin運算符來了解密鑰是否真的存在。 但是,但價格是多少?

所以,我告訴你...

in運算符和hasOwnProperty是在 Javascript 中使用屬性描述符機制的“方法”(類似於 Java 語言中的 Java 反射)。

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

屬性描述符類型用於解釋命名屬性屬性的操作和具體化。 Property Descriptor 類型的值是由命名字段組成的記錄,其中每個字段的名稱是一個屬性名稱,其值是 8.6.1 中指定的相應屬性值。 此外,任何字段都可以存在或不存在。

另一方面,調用對象方法或鍵將使用 Javascript [[Get]] 機制。 那快得多了!

基准

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

比較 JS 中的密鑰訪問 .

運算符中使用
var result = "Impression" in array;

結果是

var result = array.hasOwnProperty("Impression")
使用 hasOwnProperty
var result = array["Impression"] === undefined

結果是

168,270,439 ±0.13 ops/sec     0.02% slower 
直接訪問元素(括號樣式)
168,303,172 ±0.20%     fastest

結果是

168,270,439 ±0.13 ops/sec 0.02% slower
直接訪問元素(對象樣式)
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[].

結果是

168,303,172 ±0.20% fastest

編輯:將undefined值分配給屬性的原因是什么?

這個問題讓我很困惑。 在 Javascript 中,至少有兩個對缺失對象的引用以避免出現這樣的問題: nullundefined

null是原始值,表示有意缺少任何對象值,或簡而言之,已確認缺少值。 另一方面, undefined是一個未知值(未定義)。 如果有一個屬性稍后會以適當的值使用,請考慮使用null引用而不是undefined因為在初始時刻該屬性被確認為缺少值。

相比:

 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, ie: 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[].

建議

避免使用undefined值的對象。 盡可能直接檢查並使用null來初始化屬性值。 否則,使用緩慢in操作者或hasOwnProperty()方法。

編輯:12/04/2018 - 不再相關

正如人們所評論的,現代版本的 Javascript 引擎(除了 firefox 例外)已經改變了訪問屬性的方法。 對於這種特殊情況,當前的實現比前一個慢,但訪問密鑰和對象之間的差異可以忽略不計。

它將返回undefined

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

undefined是一個特殊的常量值。 所以你可以說,例如

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

這可能是檢查丟失密鑰的最佳方法。 但是,正如在下面的評論中指出的那樣,理論上您可能希望將實際值設為undefined 我從來不需要這樣做,也想不出為什么我想要這樣做的原因,但為了完整起見,您可以使用in運算符

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

可能只測試與數組鍵非常不同的對象屬性值

接受的答案是指Object 當心在Array上使用in運算符來查找數據而不是鍵:

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

測試數組中的現有元素: 查找項目是否在 JavaScript 數組中的最佳方法?

檢查屬性是否存在於 javascript 對象中的三種方法:

  1. !!obj.theProperty
    將值轉換為布爾值。 對除false值以外的所有值都返回true
  2. obj 中的“ theProperty
    如果屬性存在,則返回 true,無論其值如何(甚至為空)
  3. obj.hasOwnProperty('theProperty')
    不檢查原型鏈。 (因為所有對象都有toString方法,1 和 2 將在其上返回 true,而 3 可以在其上返回 false。)

參考:

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

如果您使用underscore.js庫,那么對象/數組操作就變得簡單了。

在您的情況下,可以使用 _.has 方法。 例子:

yourArray = {age: "10"}

_.has(yourArray, "age")

返回

但,

_.has(yourArray, "invalidKey")

返回

回答:

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

解釋:

in運算符將檢查對象中是否存在鍵。 如果您檢查該值是否未定義: if (myObj["key"] === 'undefined') ,您可能會遇到問題,因為您的對象中可能存在具有undefined值的鍵。

出於這個原因,最好先使用in運算符,然后在您已經知道它存在時比較鍵內的值。

這是一個我覺得非常有用的輔助函數

keyExists(key, search)可用於輕松查找對象或數組中的鍵!

只需將要查找的鍵傳遞給它,然后搜索要在其中查找的 obj(對象或數組)。

 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

它非常可靠並且跨瀏覽器運行良好。

香草js

yourObjName.hasOwnProperty(key) : true ? false;

如果要檢查對象在 es2015 中是否至少有一個屬性

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

ES6解決方案

使用Array#someObject.keys 如果給定的鍵存在於對象中,則返回true ,否則返回false

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

單行示例。

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

可選鏈操作符

 const invoice = {customer: {address: {city: "foo"}}} console.log( invoice?.customer?.address?.city ) console.log( invoice?.customer?.address?.street ) console.log( invoice?.xyz?.address?.city )

查看支持的瀏覽器列表


對於那些在他們的項目中包含lodash
有一個 lodash _.get方法試圖獲取“深”鍵:

獲取對象路徑處的值。 如果解析的值未定義,則默認值在其位置返回。

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


這將有效地檢查該鍵是否已定義,無論該鍵有多,並且如果未定義該鍵,則不會拋出可能會損害程序流程的錯誤。

最簡單的檢查方法是

"key" in object

例如:

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

返回值為true意味着該對象中存在鍵。

我們可以使用 - hasOwnProperty.call(obj, key);

underscore.js方式 -

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

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

如果要檢查對象上任何深度的任何鍵並考慮錯誤值,請考慮使用以下行作為實用函數:

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

結果

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

另請參閱此 NPM 包: https : //www.npmjs.com/package/has-deep-value

雖然這不一定檢查鍵是否存在,但它會檢查值的真實性。 哪些undefinednull屬於。

Boolean(obj.foo)

這個解決方案最適合我,因為我使用打字稿,並且'foo' in objobj.hasOwnProperty('foo')使用像這樣'foo' in obj字符串obj.hasOwnProperty('foo')來檢查密鑰是否存在並不能為我提供智能感知。

Optional Chaining ( ?. ) 運算符也可以用於此

來源: MDN/Operators/Optional_chaining

 const adventurer = { name: 'Alice', cat: { name: 'Dinah' } } console.log(adventurer.dog?.name) // undefined console.log(adventurer.cat?.name) // Dinah

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

在“數組”世界中,我們可以將索引視為某種鍵。 令人驚訝的是in運算符(這是對象的不錯選擇)也適用於數組。 不存在的鍵的返回值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]);

yourArray.indexOf(yourArrayKeyName) > -1

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

fruit.indexOf('apple') > -1

真的


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

fruit.indexOf('apple1') > -1

錯誤的

值得注意的是,自 ES11 引入以來,您可以使用空合並運算符,這大大簡化了事情:

const obj = {foo: 'one', bar: 'two'};

const result = obj.foo ?? "Not found";

上面的代碼將為 foo 中的任何“假”值返回“未找到”。 否則它將返回 obj.foo。

請參見結合空合並運算符

這些示例可以演示不同方式之間的差異。 希望它能幫助您選擇適合您需求的產品:

// 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"]

就我而言,我想檢查 LUIS 返回的 NLP 元數據,這是一個對象。 我想檢查是否存在作為字符串“FinancialRiskIntent”的鍵作為該元數據對象中的鍵。

  1. 我試圖定位我需要檢查的嵌套對象 - > data.meta.prediction.intents (僅出於我自己的目的,您的可以是任何對象)
  2. 我使用下面的代碼來檢查密鑰是否存在:

 const hasKey = 'FinancialRiskIntent' in data.meta.prediction.intents; if(hasKey) { console.log('The key exists.'); } else { console.log('The key does not exist.'); }

這是檢查我最初尋找的特定鍵。

希望這對某人有所幫助。

2021 年 - 使用新方法Object.hasOwn()替代Object.hasOwnProperty()

Object.hasOwn()旨在替代Object.hasOwnProperty()並且是一種可用的新方法(但仍未完全被所有瀏覽器如 safari 支持,但很快就會支持)

Object.hasOwn()是一個靜態方法,如果指定的對象具有指定的屬性作為它自己的屬性,則返回 true。 如果該屬性被繼承或不存在,則該方法返回 false。

 const person = { name: 'dan' }; console.log(Object.hasOwn(person, 'name'));// true console.log(Object.hasOwn(person, 'age'));// false const person2 = Object.create({gender: 'male'}); console.log(Object.hasOwn(person2, 'gender'));// false

在 Object.prototype.hasOwnProperty() 上使用它的動機是什么? - 建議在Object.hasOwnProperty()使用此方法,因為它也適用於使用Object.create(null)創建的對象以及覆蓋繼承的hasOwnProperty()方法的對象。 盡管可以通過在外部對象上調用Object.prototype.hasOwnProperty()來解決此類問題,但Object.hasOwn()克服了這些問題,因此是首選(參見下面的示例)

 let person = { hasOwnProperty: function() { return false; }, age: 35 }; if (Object.hasOwn(person, 'age')) { console.log(person.age); // true - the remplementation of hasOwnProperty() did not affect the Object }

 let person = Object.create(null); person.age = 35; if (Object.hasOwn(person, 'age')) { console.log(person.age); // true - works regardless of how the object was created }

更多關於Object.hasOwn可以在這里找到: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn

瀏覽器兼容性 - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn#browser_compatibility

使用“反射”的另一種方法

根據MDN

Reflect 是一個內置對象,它為可攔截的 JavaScript 操作提供方法。

靜態 Reflect.has() 方法的工作方式類似於作為函數的 in 運算符。

 var obj = { a: undefined, b: 1, c: "hello world" } console.log(Reflect.has(obj, 'a')) console.log(Reflect.has(obj, 'b')) console.log(Reflect.has(obj, 'c')) console.log(Reflect.has(obj, 'd'))

我應該使用它嗎?

要看。

Reflect.has()比接受的答案中提到的其他方法慢(根據我的基准測試)。 但是,如果您只在代碼中使用它幾次,我認為這種方法不會有太多問題。

JS 雙感嘆號!! 在這種情況下,標志可能會有所幫助。

const cars = {
        petrol:{
            price: 5000
        },
        gas:{
            price:8000
        }
    }

假設我們有上面的對象,並且如果您嘗試以汽油價格記錄汽車。

=> console.log(cars.petrol.price);
=> 5000

你肯定會從中得到5000。 但是如果你試圖得到一輛不存在的電動汽車,那么你會得到undefine

=> console.log(cars.electric);
=> undefine

但是使用!! 這是將變量轉換為布爾值(真或假)的簡短方法。

=> console.log(!!cars.electric);
=> false

要查找對象中是否存在鍵,請使用

Object.keys(obj).includes(key)

ES7 包含檢查 Array 是否包含項目的方法, & 是indexOf的更簡單替代方法。

新的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

請檢查JavaScript 解構的其他用途

一個快速而簡單的解決方案是將您的對象轉換為 json,然后您就可以完成這個簡單的任務:

const allowed = {
    '/login' : '',
    '/register': '',
    '/resetpsw': ''
};
console.log('/login' in allowed); //returns true

如果您使用數組,對象鍵將被轉換為整數,例如 0,1,2,3 等,因此,它始終為 false

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM