Проверка, существует ли ключ в объекте JavaScript?

2418

Как проверить, существует ли конкретный ключ в объекте или массиве JavaScript?

Если ключ не существует, и я пытаюсь получить к нему доступ, вернет ли он false? Или выбросить ошибку?

  • 1
    Все (почти все) в JavaScript является объектом или может быть приведено как единое целое. Именно здесь рождаются псевдоассоциативные массивы, как указывал @PatrickM.
  • 0
    Этот тест jsben.ch/#/WqlIl дает вам обзор наиболее распространенных способов выполнения этой проверки.
Показать ещё 1 комментарий
Теги:
object
arrays

20 ответов

3343
Лучший ответ

Проверка неопределенности не является точным способом проверки наличия ключа. Что делать, если ключ существует, но значение фактически 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, см. Этот тест

  • 72
    Наличие свойства с заданным вручную значением undefined не имеет абсолютно никакого смысла. Это был бы оксюморон на самом деле.
  • 228
    Я убежден, что есть варианты использования для преднамеренного задания свойств неопределенными.
Показать ещё 17 комментариев
252

быстрый ответ

Как проверить, существует ли какой-либо конкретный ключ в объекте или массиве JavaScript? Если ключ не существует, и я пытаюсь получить к нему доступ, он вернет false? Или выбросить ошибку?

Доступ непосредственно к отсутствующему свойству с использованием (ассоциативного) стиля массива или стиля объекта возвращает неопределенную константу.

Медленный и надежный метод оператора и hasOwnProperty

Как уже упоминалось здесь, у вас может быть объект со свойством, связанным с константой "undefined".

 var bizzareObj = {valid_key:  undefined};

В этом случае вам нужно будет использовать hasOwnProperty или у оператора, чтобы узнать, действительно ли ключ. Но, но по какой цене?

так, я говорю вам...

in operator и 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

Изображение 2051.

Использование в операторе
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

EDIT: В чем причина присвоения свойства 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 для инициализации значений свойств. В противном случае используйте метод slow in operator или hasOwnProperty().

EDIT: 12/04/2018 - НЕ СООТВЕТСТВУЕТ ЛЮБОЙ

Как отмечают люди, современные версии движков Javascript (с исключением firefox) изменили подход к свойствам доступа. Текущая реализация медленнее предыдущей для данного конкретного случая, но разница между ключом доступа и объектом пренебрежимо мала.

  • 1
    Являются ли все эти методы приемлемыми во всех широко используемых браузерах, например, IE8 +?
  • 8
    +1 для бенчмаркинга. Спасибо, это именно та информация, которую я надеялся найти. Определенно сильный аргумент для написания кода, который никогда не назначает или ожидает, что ключ будет содержать значение undefined .
Показать ещё 4 комментария
113

Он вернет 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
}
  • 0
    Да. Он возвращает неопределенное значение, независимо от того, создан ли он как объект или массив.
  • 8
    Что если ключ существует, но значение на самом деле не определено?
Показать ещё 10 комментариев
24

Принятый ответ относится к объекту. Остерегайтесь использовать оператор in в массиве для поиска данных вместо ключей:

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

Проверить существующие элементы в массиве: лучший способ найти элемент в массиве JavaScript?

21
"key" in obj

Вероятно, тестирует только значения атрибутов объекта, которые сильно отличаются от ключей массива.

  • 0
    Этот код даст значение true также для ключа, который определен в прототипе Class: function A () {}; A.prototype.b = 2; var a = new A (); Тогда «б» в а это правда. Хотя a.hasOwnProperty ('b'), конечно, ложно.
20

Три способа проверить, присутствует ли свойство в объекте javascript:

  • !! obj.theProperty
    Преобразует значение в bool. возвращает TRUE для всех, кроме значения "false"
  • 'theProperty' в obj
    Вернет true, если свойство существует, независимо от его значения (даже пустого)
  • obj.hasOwnProperty( 'theProperty')
    Не проверяет цепочку прототипов. (поскольку все объекты имеют метод toString, 1 и 2 вернут true, а 3 могут возвращать на него false).

Ссылка:

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

  • 0
    !! obj.theProperty завершается ошибкой, когда значение не определено. Пример: var a = {a : undefined, b : null}; !!aa **will return false**
13

Если вы используете библиотеку underscore.js, то операции с объектом/массивом становятся простыми.

В вашем случае может использоваться метод _.has. Пример:

yourArray = {age: "10"}

_.has(yourArray, "age")

возвращает true

Но,

_.has(yourArray, "invalidKey")

возвращает false

12

Ответ:

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

Объяснение:

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

По этой причине гораздо лучше использовать сначала оператор in, а затем сравнить значение, находящееся внутри ключа, как только вы уже знаете, что оно существует.

9

Здесь вспомогательная функция, которую я нахожу весьма полезной

Этот 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;
}

Как его использовать:

Поиск ключей в массивах

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

Он был довольно надежным и хорошо работает в кросс-браузере.

  • 4
    Это кажется немного запутанным: во-первых, при поиске массива этот метод проверяет значение , а не ключ. Во-вторых, зачем перебирать массив таким образом, если вы можете использовать встроенный метод Array.indexOf ? (если вы ищете значение, то есть)
5

Решение ES6

используя 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'));
  • 0
    Неудачно для неисчислимых свойств объекта.
  • 0
    @ Сид Дай мне пример.
Показать ещё 5 комментариев
5

vanila js

yourObjName.hasOwnProperty(key) : true ? false;

Если вы хотите проверить, имеет ли объект по крайней мере одно свойство в es2015

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

Мы можем использовать - 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);
};
2

Самый простой способ проверить это

"key" in object

например:

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

Возвращаемое значение как true подразумевает, что ключ существует в объекте.

2

Это старый вопрос, но я думаю, никогда не поздно ответить.

Представьте, что у вас есть объект "товары" и два элемента. Если вы хотите увидеть, существует ли идентификатор уже в этом объекте, вы можете использовать find()

products = [
    {
        "id": 1,
        "name": "Name 1"
    },
    {
        "id": 2,
        "name": "Name 2"
    },
  ]

  item1 = 
    {
        "id": 3,
        "name": "Name 3",
    }



  item2 = 
    {
        "id": 1,
        "name": "Name 1",
    }



  if(products.find(x => x.id === item1.id)){
    console.log('id is in products');
  }else {
    console.log('id is not in products');
  }
  if(products.find(x => x.id === item2.id)){
    console.log('id is in products');
  }else {
    console.log('id is not in products');
  }

Журнал:

id is not in products
id is in products
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 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

Хотя это обязательно проверяет, существует ли ключ, он проверяет правдоподобие значения. Какой undefined и null подпадают под.

Boolean(obj.foo)

Это решение работает лучше всего для меня, потому что я использую машинопись и использую такие строки, как 'foo' in obj или obj.hasOwnProperty('foo') чтобы проверить, существует ли ключ или нет, не предоставляет мне intellisense.

1

Для тех, у кого lodash включен в их проект:
Существует lodash _. get метод, который пытается получить "глубокие" клавиши:

Возвращает значение по пути объекта. Если разрешенное значение undefined, 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>

Это будет эффективно проверять, установлен ли этот ключ, однако глубокий, и не будет вызывать ошибку, которая может нанести вред потоку вашей программы, если этот ключ не определен.

0

yourArray.indexOf(yourArrayKeyName)> -1

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

fruit.indexOf('apple') > -1

правда


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

fruit.indexOf('apple1') > -1

ложный

0

Если вы хотите проверить любой ключ на любой глубине объекта и учесть значения Falsey, рассмотрите эту строку для служебной функции:

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

0

Новое потрясающее решение с JavaScript Destructuring:

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 Destructuring

Ещё вопросы

Сообщество Overcoder
Наверх
Меню