Питання Перевірка наявності ключа в об'єкті JavaScript?


Як перевірити наявність певного ключа в об'єкті JavaScript або масиві?

Якщо ключ не існує, і я намагаюся отримати доступ до нього, чи повернеться він помилково? Або кинути помилку?


2228
2017-07-08 13:21


походження


Усе (майже все) в JavaScript є об'єктом або його можна віддати як одну. Тут народжуються псевдоасоціативні масиви, як зазначив @ PatrickM. - Andrew Larsson
цей еталон jsben.ch/#/WqlIl дає огляд найбільш поширених способів досягнення цієї перевірки. - EscapeNetscape


Відповіді:


Перевірка на невизначеність - це не точний спосіб перевірки, чи існує ключ. Що робити, якщо ключ існує, але значення насправді 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, дивись це орієнтир


3087
2017-07-08 15:51



Маючи властивість з ручним визначеним значенням невизначеною, абсолютно не має сенсу. Це буде оксюморон насправді. - joebert
Я переконаний, що існують випадки використання, якщо властивості навмисно встановлені на невизначені. - Ates Goral
Дійсний випадок використання: Gecko 1.9.1 [Firefox 3.5] не має властивості window.onhashchange. Gecko 1.9.2 [Firefox 3.6] має цю властивість невизначену (до зміни хешу). Щоб визначити хеш-історію або версію браузера, потрібно використовувати window.hasOwnProperty ("onhashchange"); - SamGoody
Подібна проблема існує в PHP, де null == nonexistent: stackoverflow.com/q/418066/372654 і, на жаль, нуль також використовується там. - Halil Özgür
@joebert Просто тому, що щось дурниця не означає, що ви не будете стикатися з ним у виробничому коді. Є багато бібліотек, які роблять безглузді речі. - Crashworks


швидка відповідь

Як перевірити наявність певного ключа в об'єкті JavaScript або масиві?   Якщо ключ не існує, і я намагаюся отримати доступ до нього, чи повернеться він помилково? Або кинути помилку?

Доступ безпосередньо до пропущеної властивості, використовуючи стиль масиву (асоціативний) або стиль об'єкта, повертатиме невизначено постійна

Повільний і надійний в оператор і hasOwnProperty метод

Як вже згадувались тут, ви можете мати об'єкт з властивістю, пов'язаною з "невизначеною" константою.

 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

Comparing key access in JS.

Використовуючи в оператор
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 є невідомим значенням (не визначено). Якщо є власність, яка буде використовуватися пізніше за допомогою a правильний значення розглянути використання 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() метод

EDIT: 04.12.2018 - НЕ ВІДПОВІДНЕ АНІМОР

Як прокоментували люди, сучасні версії Javascript-драйверів (за винятком Firefox) змінили підхід до властивостей доступу. Поточна реалізація є більш повільною, ніж попередня, для конкретного випадку, але різниця між ключем доступу та об'єктом є неуважною.


224
2018-02-27 16:38



Усі ці методи є прийнятними для всіх загальнодоступних веб-переглядачів, наприклад IE8 +? - Justin
@ Justin Так. Він повинен працювати. Ви можете перевірити безпосередньо на jsperf.com/checking-if-a-key-exists-in-a-javascript-array. - rdllopes
+1 для порівняльного аналізу. Спасибі, це саме інформація, яку я сподівався знайти. Напевно сильний аргумент для написання коду, який ніколи не призначає або не очікує, що ключ містить його значення невизначено. - T.J. Compton
Однією з причин, я хотів би встановити невизначену хеш-значення, це те, що я дійсно хотів видалити цей ключ властивості з хешу, але delete hash[key] є набагато повільніше ніж  hash[key] = undefined. Звичайно, в даному випадку немає сенсу для мене це потрібно in оператор, але він діє як контрприклад "ми завжди повинні уникати встановлення значення до невизначеності". - Alan Tam
Як зазначив @ HüseyinYağlı, якщо ви перевіряєте jsperf посилання, продуктивність помітно змінилася між різними методами для більшості браузерів, оскільки ця відповідь була спочатку написана. Firefox - одна з небагатьох, яка все ще має значні переваги, використовуючи масив або об'єктні методи, але для багатьох інших браузерів відмінності незначні. - kevinmicke


Це повернеться 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
}

114
2017-07-08 13:24



Що робити, якщо ключ існує, але значення насправді не визначено? - Ates Goral
Ви повинні використовувати === замість == при порівнянні з undefined, в іншому випадку нуль буде порівнювати до undefined. - Matthew Crumley
Елі ваша відповідь не є повністю точною. Тому що в будь-якому випадку (і, звичайно, це ніколи не повинно бути зроблено) undefined - це не особлива постійна величина. Фактично, це не зарезервоване ключове слово, і ви можете переписати його, скажемо, наприклад var undefined = 42;. Під час тестування на невизначені реквізити завжди слід використовувати ((typeof variable) === "undefined"). - ssice
@ssice undefined не є властивістю для записування відповідно до специфікації ecma-international.org/ecma-262/5.1/#sec-15.1.1.3 - therealrootuser
У попередніх версіях JavaScript, 'undefined' та 'NaN' були змінні змінні, які можна перевизначити або призначити інші значення. Це було погано. Він був виправлений в ECMAScript 5. - jkdev


The прийнята відповідь відноситься до Об'єкт. Остерігайтеся, використовуючи in оператор на Масив щоб знайти дані замість клавіш:

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

Щоб протестувати існуючі елементи в масиві: Найкращий спосіб знайти, чи є елемент у масиві JavaScript?


22
2017-07-01 12:45





"key" in obj

Схоже, тестування лише об'єктів атрибутів об'єктів, які сильно відрізняються від ключів масиву


20
2018-04-25 15:45



Цей код дасть вірний також ключ, який визначено в прототипі класу: функція A () {}; A.prototype.b = 2; var a = new A (); Тоді "b" в a істинно. Хоча a.hasOwnProperty ('b'), звичайно, є помилковим. - Alexander


Три способи перевірки наявності властивості об'єкта javascript:

  1. Об'єкт власності
    Буде перетворено значення в bool. повертає значення TRUE для всіх, крім значення "false"
  2. 'theproperty' в obj
    Повернеться true, якщо властивість існує незалежно від його значення (навіть порожнє)
  3. obj.hasOwnProperty ('theproperty')
    Не перевіряє ланцюжок прототипів. (оскільки всі об'єкти мають метод 'toString', 1 і 2 повернуться на нього, а 3 - на ложі.)

Довідка:

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


20
2017-11-12 09:19





Якщо ви використовуєте underscore.js тоді бібліотека об'єктів / масивів стає простою.

У вашому випадку метод _.has може бути використаний. Приклад:

yourArray = {age: "10"}

_.has(yourArray, "age")

повертає правда 

Але,

_.has(yourArray, "invalidKey")

повертає помилковий


13
2018-05-29 19:37





Відповідь:

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

Пояснення:

The in Оператор перевірить, чи існує ключ у об'єкті. Якщо ви перевірили, чи значення не визначено: if (myObj["key"] === 'undefined'), ви можете зіткнутися з проблемами, тому що ключ може існувати у вашому об'єкті з undefined вартість

З цієї причини набагато краще практикувати перше використання in оператор, а потім порівняти значення, яке знаходиться всередині ключа, як тільки ви вже знаєте, що він існує.


10
2018-06-22 02:29





Ось допоміжна функція, яку я вважаю корисною

Це keyExists(key, search) може бути використаний для зручного пошуку ключа в об'єктах або масивах!

Просто передайте його ключ, який ви хочете знайти, і пошук об'єкта (об'єкта або масиву), який ви хочете його знайти.

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

Як його використовувати:

Пошук ключів у масиві

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

Пошук ключів у об'єктах

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

Вона була досить надійною і добре працює в різних браузерах.


9
2018-03-05 12:56



Це здається трохи заплутаним: по-перше, під час пошуку масиву цей метод перевіряє а вартість, не ключ. По-друге, чому ітерація через масив таким чином, коли ви можете використовувати вбудований Array.indexOf метод (якщо ви шукаєте значення, тобто) - Nick F


ваніла Дж

yourObjName.hasOwnProperty(key) : true ? false;

Якщо ви хочете перевірити, чи має об'єкт щонайменше один властивість в es2015

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

4
2018-01-25 15:39