Як перевірити, чи існує певний ключ в об’єкті або масиві JavaScript?
Якщо ключ не існує, і я намагаюся отримати доступ до нього, чи повернеться він помилковим? Або кинути помилку?
property.key = property.key || 'some default value'
Як перевірити, чи існує певний ключ в об’єкті або масиві JavaScript?
Якщо ключ не існує, і я намагаюся отримати доступ до нього, чи повернеться він помилковим? Або кинути помилку?
property.key = property.key || 'some default value'
Відповіді:
Перевірка на невизначеність не є точним способом перевірити наявність ключа. Що робити, якщо ключ існує, але значення є насправді undefined
?
var obj = { key: undefined };
obj["key"] !== undefined // false, but the key exists!
Натомість слід використовувати in
оператор:
"key" in obj // true, regardless of the actual value
Якщо ви хочете перевірити, чи не існує ключа, не забудьте скористатися дужками:
!("key" in obj) // true if "key" doesn't exist in object
!"key" in obj // ERROR! Equivalent to "false in obj"
Або, якщо ви хочете особливо перевірити властивості об’єкта об'єкта (а не успадковані властивості), використовуйте hasOwnProperty
:
obj.hasOwnProperty("key") // true
Для порівняння продуктивності між методами, які in
, hasOwnProperty
і клавіша undefined
, побачити цей тест
Як перевірити, чи існує певний ключ в об’єкті або масиві JavaScript? Якщо ключ не існує, і я спробую отримати доступ до нього, чи повернеться він помилковим? Або кинути помилку?
Доступ безпосередньо до відсутньої властивості за допомогою (асоціативного) стилю масиву чи стилю об’єкта поверне невизначену константу.
Як люди вже згадували тут, у вас може бути об’єкт із властивістю, пов'язаною з "невизначеною" константою.
var bizzareObj = {valid_key: undefined};
У такому випадку вам доведеться використовувати hasOwnProperty або в оператора, щоб знати, чи ключ дійсно є. Але, але якою ціною?
так, я вам кажу ...
в операторі та hasOwnProperty - це "методи", які використовують механізм Дескриптора властивостей у Javascript (подібний до відображення Java в мові Java).
http://www.ecma-international.org/ecma-262/5.1/#sec-8.10
Тип Дескриптора властивостей використовується для пояснення маніпулювання та переробки названих атрибутів властивості. Значення типу "Дескриптор властивості" - це записи, що складаються з іменованих полів, де ім'я кожного поля є ім'ям атрибута, а його значення - відповідним значенням атрибута, як зазначено в 8.6.1. Крім того, будь-яке поле може бути присутнім або відсутнім.
З іншого боку, для виклику об'єктного методу чи ключа використовується механізм Javascript [[Get]]. Це набагато швидше!
http://jsperf.com/checking-if-a-key-exists-in-a-javascript-array
.
Використання в операторіvar result = "Impression" in array;
Результат був
12,931,832 ±0.21% ops/sec 92% slower
Використання hasOwnProperty
var result = array.hasOwnProperty("Impression")
Результат був
16,021,758 ±0.45% ops/sec 91% slower
Доступ до елементів безпосередньо (стиль дужок)
var result = array["Impression"] === undefined
Результат був
168,270,439 ±0.13 ops/sec 0.02% slower
Доступ до елементів безпосередньо (стиль об'єкта)
var result = array.Impression === undefined;
Результат був
168,303,172 ±0.20% fastest
undefined
значення?Це питання спантеличує мене. У Javascript є щонайменше дві посилання на відсутні об'єкти, щоб уникнути таких проблем: null
іundefined
.
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, 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[].
Уникайте об'єктів зі undefined
значеннями. Перевірте безпосередньо, коли можливо, і використовуйте null
для ініціалізації значень властивостей. В іншому випадку використовуйте повільний in
оператор або hasOwnProperty()
метод.
Як коментують люди, сучасні версії двигунів Javascript (за винятком firefox) змінили підхід до властивостей доступу. Поточна реалізація проходить повільніше, ніж попередня для цього конкретного випадку, але різницю між ключем доступу та об'єктом нехтувати.
delete hash[key]
це набагато повільніше, ніж hash[key] = undefined
. Звичайно, в цьому випадку для мене немає сенсу потребувати in
оператора, але він виступає як контрприклад "ми завжди повинні уникати встановлення значення для невизначеного".
Це повернеться 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
}
var undefined = 42;
. Під час тестування невизначених реквізитів завжди слід використовувати ((typeof variable) === "undefined")
.
undefined
також не буде перезаписано властивість згідно специфікації ecma-international.org/ecma-262/5.1/#sec-15.1.1.3
Прийнятий відповідь відноситься до об'єкту . Обережно використовуйте in
оператор у масиві для пошуку даних замість ключів:
("true" in ["true", "false"])
// -> false (Because the keys of the above Array are actually 0 and 1)
Для тестування наявних елементів у масиві: найкращий спосіб виявити, чи є елемент у масиві JavaScript?
"key" in obj
Ймовірно, тестується лише значення атрибутів об'єкта, які сильно відрізняються від ключів масиву
Три способи перевірити наявність властивості в об’єкті javascript:
Довідка:
var a = {a : undefined, b : null}; !!a.a **will return false**
Якщо ви використовуєте бібліотеку 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
Це було досить надійно і працює добре крос-браузер.
Array.indexOf
метод? (якщо ви шукаєте значення, тобто)
vanila js
yourObjName.hasOwnProperty(key) : true ? false;
Якщо ви хочете перевірити, чи має об’єкт принаймні одне властивість у es2015
Object.keys(yourObjName).length : true ? false
за допомогою Array#some
та Object.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'));
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);
};
lodash
включив у свій проект: Отримує значення на шляху об'єкта. Якщо вирішене значення не визначене, на його місце повертається defaultValue.
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>
Це ефективно перевірить, чи визначений цей ключ, наскільки глибокий , і не призведе до помилки, яка може зашкодити потоку вашої програми, якщо цей ключ не визначений.
Хоча це не обов'язково перевіряє, чи існує ключ, він перевіряє правдивість значення. Які undefined
і null
підпадають.
Boolean(obj.foo)
Це рішення найкраще працює для мене, тому що я використовую typecript, і використовуючи рядки, подібні до цього, 'foo' in obj
або obj.hasOwnProperty('foo')
перевіряти, чи існує ключ чи ні, це не дає мені інтелігенції.
Якщо ви хочете перевірити наявність будь-якого ключа на будь-якій глибині об'єкта і врахувати значення фальси, розгляньте цей рядок для функції корисності:
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
У світі "масиву" ми можемо дивитись на індекси як на деякі клавіші. Що дивно, що 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
помилковий
Цей приклад може продемонструвати відмінності між різними способами. Сподіваємось, це допоможе вам вибрати потрібний для ваших потреб:
// 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"]
Нове дивовижне рішення з руйнуванням 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