Как проверить, есть ли у объекта определенное свойство в JavaScript?
Рассматривать:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
Это лучший способ сделать это?
('propertyName' в объекте)? 'property is there': 'свойство is not there'
@styfle спасибо за тест jsperf. in и hasOwnProperty вышли на путь медленнее, чем другие для меня (на 98% медленнее). Я не удивлен тем, что hasOwnProperty работает медленнее, но меня удивляет in.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Да, это так :) Я думаю, вы также можете сделать Object.prototype.hasOwnProperty.call(x, 'key'), который также должен работать, если x имеет свойство hasOwnProperty :)
Но это проверка собственных свойств. Если вы хотите проверить, есть ли у него свойство, которое также может быть унаследовано, вы можете использовать typeof x.foo != 'undefined'.
if (x.key !== undefined)
Армин Ронахер кажется уже имеет опередить меня, но:
Object.prototype.hasOwnProperty = function(property) {
return this[property] !== undefined;
};
x = {'key': 1};
if (x.hasOwnProperty('key')) {
alert('have key!');
}
if (!x.hasOwnProperty('bar')) {
alert('no bar!');
}
Более безопасное, но более медленное решение, как указано от Конрад Рудольф и Армин Ронахер будет:
Object.prototype.hasOwnProperty = function(property) {
return typeof this[property] !== 'undefined';
};
Я не думаю, что этого достаточно. x.hasOwnProperty('toString') === true;
Не просить не соглашаться, а понимать. Есть ли точка, в которой x.hasOwnProperty вернет что-либо, кроме логического значения true или false? Если нет, то опубликованный код должен работать каждый раз. Я полагаю, возможно, если бы метод был переопределен, но тогда полагаться на результат никогда не было бы надежным, если вы не знаете метод переопределения.
Я думаю, у нас недопонимание. Я имею в виду, что, используя ваш метод, он скажет, что toString - это собственное свойство, но это не так.
Object.prototype уже имеет встроенный правильный hasOwnProperty. Перезапись его неправильной реализацией (1. Свойства могут иметь значение undefined, 2. Это приведет к ложным срабатываниям для унаследованных свойств) - просто ужасно плохая идея. Неправильные ответы можно и нужно удалять. Я не знаю, могли бы вы сделать это в сентябре 2008 г. когда вы увидели ответ Ресига, поэтому комментирую, чтобы предложить сделать это сейчас.
Хорошо, похоже, я получил правильный ответ, если только вы не хотите унаследованные свойства:
if (x.hasOwnProperty('key'))
Вот еще несколько вариантов включения унаследованных свойств:
if (x.key) // Quick and dirty, but it does the same thing as below.
if (x.key !== undefined)
Предостережение x.hasOwnProperty ('key') может быть истинным, в то время как x.key! == undefined не истинно.
Для var x = { key: false }; метод x.key будет неправильным.
если (x.key) неверен, как если бы x = {key: 0}, он не пройдет проверку.
if (typeof x.key != "undefined") {
}
Потому что
if (x.key)
завершается ошибкой, если x.key преобразуется в false (например, x.key = "").
Не будет правильно. Попробуйте следующий объект const x = {key: undefined};, который вернет false с этим решением, а x.hasOwnProperty('key')); // true и Reflect.has(x, 'key')); // true. Свойство действительно существует, но имеет значение undefined.
Примечание: следующее в настоящее время в значительной степени устарело благодаря строгому режиму и hasOwnProperty. Правильное решение - использовать строгий режим и проверять наличие свойства с помощью obj.hasOwnProperty. Этот ответ предшествует обе эти вещи, по крайней мере, так же широко реализованы (да, он такой старый). Примем следующее историческое примечание.
Имейте в виду, что undefined (к сожалению) является нет зарезервированным словом в JavaScript, если вы не используете строгий режим. Следовательно, у кого-то (очевидно, у кого-то другого) может возникнуть грандиозная идея переопределить его, взломав ваш код.
Поэтому более надежным методом является следующий:
if (typeof(x.attribute) !== 'undefined')
С другой стороны, этот метод более подробный и медленный. : - /
Распространенной альтернативой является обеспечение того, чтобы undefined был на самом деле undefined, например помещая код в функцию, которая принимает дополнительный параметр undefined, которому не передается значение. Чтобы гарантировать, что он не передал значение, вы можете просто немедленно вызвать его самостоятельно, например:
(function (undefined) {
… your code …
if (x.attribute !== undefined)
… mode code …
})();
Просто любопытно, поскольку void 0 определен как возвращающий канонический undefined, можно ли сделать x.attribute !== void 0?
Брайан: Я не эксперт, но это кажется отличным способом сделать все правильно.
Если бы знаменитый «кто-то другой» изменил определение undefined, я думаю, что лучше всего было бы переписать ЭТО код.
undefined = (function () {}()); if (a.attribute !== undefined) 'foo';
Лучше всего иметь твердую неопределенную переменную, работать в замыкании и иметь непревзойденную сигнатуру функции: (function (undefined) { // undefined is actually undefined here })();
Начиная со строгого режима ES5, вы больше не можете переопределить undefined, но вам нужно не забыть включить строгий режим. :) Кроме того, этот ответ не проверяет, есть ли у объекта какое-либо свойство, а проверяет, является ли свойство неопределенным (включая как существующие, так и несуществующие свойства).
@ BrianM: Ваше предложение с x.attribute !== void 0 (или void(0)) отлично работает в моем тесте.
@evanrmurphy Не используйте это, это серьезно устарело (см. примечание в начале моего ответа).
Меня действительно сбивают с толку полученные ответы - большинство из них совершенно неверны. Конечно, у вас могут быть свойства объекта с неопределенными, нулевыми или ложными значениями. Таким образом, простое сокращение проверки собственности до typeof this[property] или, что еще хуже, x.key даст вам совершенно вводящие в заблуждение результаты.
Это зависит от того, что вы ищете. Если вы хотите знать, содержит ли объект физически свойство (и не исходит ли оно откуда-то из цепочки прототипов), тогда object.hasOwnProperty - это то, что вам нужно. Все современные браузеры его поддерживают. (Он отсутствовал в более старых версиях Safari - 2.0.1 и старше, но эти версии браузера редко используются.)
Если то, что вы ищете, это то, что объект имеет свойство, которое является итеративным (когда вы перебираете свойства объекта, оно появится), тогда выполнение: prop in object даст вам желаемый эффект.
Поскольку вы, вероятно, захотите использовать hasOwnProperty, и учитывая, что вам может понадобиться запасной метод, я представляю вам следующее решение:
var obj = {
a: undefined,
b: null,
c: false
};
// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}
function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}
Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};
var obj2 = new Class();
// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
if ( Object.prototype.hasOwnProperty ) {
var hasOwnProperty = function(obj, prop) {
return obj.hasOwnProperty(prop);
}
}
// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}
Вышеупомянутое рабочее кроссбраузерное решение для hasOwnProperty с одной оговоркой: он не может различить случаи, когда идентичное свойство находится в прототипе и в экземпляре - оно просто предполагает, что оно исходит от прототипа. Вы можете изменить его на более снисходительный или строгий, в зависимости от вашей ситуации, но, по крайней мере, это должно быть более полезным.
@grantwparks Если вы создаете простой плагин для слайдера и хотите проверить наличие элемента параметров, то этого может быть больше, чем нужно. Можно просто сделать что-нибудь вроде var w = opts.w || 100;. Но если вы занимаетесь чем-то вроде библиотеки, вам, возможно, придется пойти немного дальше в некоторых частях.
@ kralco626: Да, в настоящее время я считаю, что использовать hasOwnProperty () довольно безопасно, но для действительно безопасного кросс-браузерного решения используйте John's.
А как насчет изменения временный__proto__ на null? Простой вариант: function hasOwnProperty(obj, prop) { var temp = obj.__proto__; obj.__proto__ = null; var ret = prop in obj; obj.__proto__ = temp; return ret; } (следует добавить случай с obj.constructor.prototype).
@Kasztan __proto__ нестандартен и не работает в некоторых старых браузерах. И даже с недавним добавлением Object.getPrototypeOf стандарт говорит, что вы все еще не можете изменить прототип существующего объекта.
Ответы Джона Ресига, похоже, не работают в IE8, посмотрите, как это не работает в этой живой демонстрации jsbin.com/tovaburefeva/1/edit?js,output. Думаю это потому, что hasOwnProperty() "is not supported on host objects for Internet Explorer 8 and below" видит msdn.microsoft.com/en-us/library/ie/328kyd6z(v=vs.94).aspx а также stackoverflow.com/questions/8157700/…
Цикл for(prop in object) выполняет итерацию только по перечислимым свойствам. Однако prop in object проверяет, имеет ли object свойство prop где-нибудь в цепочке прототипов, независимо от того, перечислимо ли оно или нет.
В качестве примечания к функциям, объявленным внутри if, это работает во всех известных мне современных браузерах, но не поддерживается PhantomJS.
Поскольку ECMA Script Version 6 включает функцию Reflect, это предпочтительный путь. У него есть has () и get (), что позволяет очень легко создать оболочку для получения Safe-Arguments. Не все браузеры могут поддерживать эту функцию (не в IE и Opera), но скоро это изменится. Используйте ECMA «использовать версию 6», чтобы обеспечить правильную версию скрипта.
Предупреждение: не используйте проверку in для примитивов.
Давайте прорежем здесь некоторую путаницу. Во-первых, давайте упростим, предположив, что hasOwnProperty уже существует; это верно для подавляющего большинства используемых в настоящее время браузеров.
hasOwnProperty возвращает истину, если переданное ему имя атрибута было добавлено к объекту. Он полностью не зависит от присвоенного ему фактического значения, которое может быть в точности undefined.
Следовательно:
var o = {}
o.x = undefined
var a = o.hasOwnProperty('x') // a is true
var b = o.x === undefined // b is also true
Тем не мение:
var o = {}
var a = o.hasOwnProperty('x') // a is now false
var b = o.x === undefined // b is still true
Проблема в том, что происходит, когда объект в цепочке прототипов имеет атрибут со значением undefined? hasOwnProperty будет ложным для него, как и !== undefined. Тем не менее, for..in все равно будет указывать его в списке.
Суть в том, что нет кроссбраузерного способа (поскольку Internet Explorer не предоставляет __prototype__) для определения того, что конкретный идентификатор не был прикреплен к объекту или чему-либо в его цепочке прототипов.
С Underscore.js или (даже лучше) Лодаш:
_.has(x, 'key');
Что вызывает Object.prototype.hasOwnProperty, но (а) короче для ввода, и (б) использует «безопасную ссылку на hasOwnProperty» (т.е. работает, даже если hasOwnProperty перезаписан).
В частности, Lodash определяет _.has как:
function has(object, key) {
return object ? hasOwnProperty.call(object, key) : false;
}
// hasOwnProperty = Object.prototype.hasOwnProperty
Я предполагаю, что это потому, что «добавить эту библиотеку» редко бывает популярным решением, даже когда вопрос касается сложных манипуляций с DOM, а ответ - «используйте jQuery».
Я понимаю вашу точку зрения, @sudowned, спасибо. Между прочим, если бы кто-то не хотел включать всю библиотеку lodash, можно было бы скомпилировать подкомпоненты или npm install lodash.has, который предоставляет модуль npm только с функцией has, которая компилируется до 175 байт при минификации. Также полезно взглянуть на lodash.has/index.js, чтобы увидеть, как работает очень популярная и надежная библиотека.
и версии lodash работают с этим: .has(undefined, 'someKey') => false, а underscore возвращает undefined
Спасибо @BradParks - я на самом деле не смотрел документацию для версии underscore, поэтому я уверен, что это может быть полезно для тех, кто это читает.
Спасибо @ brian-m-hunt. Я уже включил lodash, начал поиски еще до того, как должен был стать RTFM.
Я не верю, что использование библиотеки является приемлемым ответом, потому что вопрос задается «в JavaScript», а не «с использованием библиотеки JavaScript».
Всем, кто жалуется на добавление lodash в качестве «еще одной» зависимости: это довольно распространенная (если не самая распространенная) библиотека для такого рода вещей. Удачи, изобретая велосипед.
Даже если вы хотите изобрести колесо, проверка существующих колес - неплохая идея.
Кроме того, OP, возможно, даже не знал об этом. Поэтому слова «в JavaScript» или «с JQuery» не означают, что они не открыты для новых библиотек, о существовании которых они, возможно, не знали, и просто пытались использовать базовый Javascript или JQuery, потому что думали, что это все, что у них было в распоряжении для это. Но выбранный ответ, в котором упоминается использование hasOwnProperty, является самым простым способом сделать это.
Ради любви к Богу используйте Lodash или любую другую доступную библиотеку, пока JS не разберется со своей красивой, мелкой головкой. По крайней мере, если вы пойдете по этому пути, вы избавитесь от смехотворного количества прыжков через кольцо для совместимости с браузером. Проблема решена. Двигаться дальше.
Преимущество _.has в том, что вы можете использовать точечную нотацию для проверки глубоко вложенных атрибутов, например _.has (myObject, 'a.b.c');
Использовать:
var x = {
'key': 1
};
if ('key' in x) {
console.info('has');
}Следует отметить, что он работает с «объектами» в узком смысле, поэтому, объявленный как {} или созданный с помощью конструктора, он не принимает массивы или примитивы. Не то чтобы OP этого требовал, но в некоторых других ответах представлены более широкие методы (работа с массивами, строками и т. д.)
@ РСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ спасибо, что указали на это (принятый ответ не содержит подробностей о том, почему следует использовать оператор in или нет. Также обратите внимание, что оператор in имеет отличную поддержку браузера IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+stackoverflow.com/questions/2920765/…
Оператор in также проверяет свойства прототипа, тогда как hasOwnProperty выполняет итерацию только по свойствам, определенным пользователем. Ссылка: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
'key' in xделать работает с массивами. Доказательство: stackoverflow.com/questions/33592385/…
Кажется, лучший и самый короткий вариант
Если вы ищете недвижимость, тогда "нет". Вы хотите:
if ('prop' in obj) { }
В общем, вам не нужно беспокоиться о том, исходит ли свойство от прототипа или объекта.
Однако, поскольку вы использовали «ключ» в образце кода, похоже, что вы обрабатываете объект как хэш, и в этом случае ваш ответ будет иметь смысл. Все ключи хэшей будут свойствами объекта, и вы избегаете дополнительных свойств, вносимых прототипом.
Ответ Джона Ресига был очень подробным, но я думал, что это не совсем понятно. Особенно, когда использовать "'prop' в obj".
Отметим, что оператор in имеет отличную поддержку браузера IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+stackoverflow.com/questions/2920765/…
Как указано в другом комментарии относительно использования оператора in: «он работает с« объектами »в узком смысле, поэтому объявлен как {} или создан с помощью конструктора, он не принимает массивы или примитивы. Не то, чтобы OP этого требовал, но в некоторых других ответах представлены более широкие методы (работа с массивами, строками и т. д.) "
Комментируя причину, меня дважды отвергали без комментариев. Но мне все равно нравится мой ответ. Возможно, тот, кто это сделал, хотел получить «исчерпывающий» ответ для всех способов тестирования всех типов свойств .. Но мой ответ концептуален и поэтому краток. Re: Адриен Бе, неисчислимое свойство - это свойство, которое не предназначено для общей пользовательской области, поэтому концептуально 'in' в порядке;)
Вы можете использовать оператор in, чтобы проверить, существует ли свойство для объекта:
x = {'key': 1};
alert("key" in x);
Вы также можете просмотреть все свойства объекта, используя цикл for - in, а затем проверить конкретное свойство:
for (prop in x) {
if (prop == "key") {
//Do something
}
}
Вы должны учитывать, является ли это свойство объекта перечислимым или нет, потому что неперечислимые свойства не будут отображаться в цикле for-in. Кроме того, если перечислимое свойство дублирует неперечислимое свойство прототипа, оно не будет отображаться в Интернет-технологии и ранее.
Если вам нужен список всех свойств экземпляра, будь то перечислимые или нет, вы можете использовать
Object.getOwnPropertyNames(x);
Это вернет массив имен всех свойств, существующих в объекте.
Наконец, вы можете использовать оператор typeof, чтобы напрямую проверить тип данных свойства объекта:
if (typeof x.key == "undefined") {
alert("undefined");
}
Если свойство не существует для объекта, он вернет строку undefined. В противном случае он вернет соответствующий тип свойства. Однако обратите внимание, что это не всегда допустимый способ проверить, есть ли у объекта свойство или нет, потому что у вас может быть свойство, для которого установлено значение undefined, и в этом случае использование typeof x.key все равно вернет true (даже если ключ все еще в объекте).
Обновление: вы можете проверить, существует ли свойство, сравнив его с неопределенным свойством javascript.
if (x.key === undefined) {
alert("undefined");
}
Это должно работать, если ключ не был специально установлен на undefined на объекте x
Если проверяемый вами ключ хранится в Переменная, вы можете проверить его следующим образом:
x = {'key': 1};
y = 'key';
x[y];
Чем это концептуально отличается от простого тестирования x ['key']? И чем это отличается от x.key? Кроме, конечно, доступа к массиву ..
Другой относительно простой способ - использовать Object.keys. Это возвращает array, что означает, что вы получаете все функции массива.
var noInfo = {};
var info = {something: 'data'};
Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true
Хотя мы живем в мире с отличной поддержкой браузеров. Поскольку этот вопрос настолько старый, я подумал, что добавлю следующее: Это безопасно использовать с JavaScript v1.8.5.
Верно, но что, если вы хотите узнать, есть ли у info свойство с другим именем? Думаю, это то, что ищет OP.
Тогда вы бы сделали Object.keys(info).indexOf('someotherthing') !== -1
Что такое "JS v1.8.5"? «JavaScript v1.8.5» *? Похоже, он не соответствует ни одной версии ECMAScript (версия 8 была выпущена в 2017 году). jQuery 1.8 был выпущен в 2012 году.
Хорошо, JavaScript 1.8.5 был выпущен в 2011 году вместе с Firefox 4 (2011-03-22). Первая версия ECMAScript 5 (связанная с) относится к 2009 году.
hasOwnProperty «может использоваться, чтобы определить, имеет ли объект указанное свойство как прямое свойство этого объекта; в отличие от оператора in, этот метод не проверяет цепочку прототипов объекта».
Поэтому, скорее всего, для того, что кажется вашим вопросом, вы не хотите использовать hasOwnProperty, который определяет, существует ли свойство как прикрепленный непосредственно к самому объекту ,.
Если вы хотите определить, существует ли свойство в цепочке прототипов, вы можете использовать его следующим образом:
if (prop in object) { // Do something }
Я получаю сообщение «Невозможно использовать оператор 'in' для поиска 'prop' в myObject»
Вот еще один вариант для конкретного случая. :)
Если вы хотите протестировать член объекта и хотите узнать, установлено ли для него что-то иное, кроме:
тогда вы можете использовать:
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
Компактный и удобный
Линтеру это не понравится: eslint.org/docs/rules/no-extra-boolean-cast
Вы также можете использовать объект ES6 Reflect:
x = {'key': 1};
Reflect.has( x, 'key'); // returns true
Документацию по MDN для Reflect.has можно найти в здесь.
The static
Reflect.has()method works like the in operator as a function.
Для тестирования простых объектов используйте:
if (obj[x] !== undefined)
Если вы не знаете, какой это тип объекта, используйте:
if (obj.hasOwnProperty(x))
Все остальные варианты медленнее ...
Оценка производительности 100000000 циклов под Node.js для пяти вариантов, предложенных здесь другими:
function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }
Оценка говорит нам, что если мы специально не хотим проверить цепочку прототипов объекта, а также сам объект, мы не должны использовать общую форму:
if (X in Obj)...
Это от 2 до 6 раз медленнее в зависимости от варианта использования.
hasKey1 execution time: 4.51 s
hasKey2 execution time: 0.90 s
hasKey3 execution time: 0.76 s
hasKey4 execution time: 0.93 s
hasKey5 execution time: 2.15 s
В итоге, если ваш Obj не обязательно является простым объектом, и вы хотите избежать проверки цепочки прототипов объекта и убедиться, что x принадлежит непосредственно Obj, используйте if (obj.hasOwnProperty(x))....
В противном случае, при использовании простого объекта и не беспокоясь о цепочке прототипов объекта, использование if (typeof(obj[x]) !== 'undefined')... является самым безопасным и быстрым способом.
Если вы используете простой объект в качестве хеш-таблицы и никогда не делаете ничего странного, я бы использовал if (obj[x])..., поскольку я считаю его более читаемым.
Решение ECMAScript 6 с отражением. Создайте обертку вроде:
/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj The object or array to be searched.
@param key The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
"use strict";
var retVal = (typeof defVal === 'undefined' ? "" : defVal);
if ( Reflect.has( obj, key) ) {
return Reflect.get( obj, key);
}
return retVal;
} // getSafeReflectArg
Это лучший способ сделать это, когда вы нацеливаетесь на> = ES6?
Имхо, это самый короткий и простой ответ, но, возможно, не самый быстрый в исполнении кода. Но скорость (больше) не проблема.
Зачем дважды размещать Такой же ответ? Вы можете просто проголосовать за существующую ...?
Вам нужно использовать метод object.hasOwnProperty(property). Он возвращает истину, если объект имеет свойство, и ложь, если объект не имеет.
Существует метод hasOwnProperty, который существует для объекта, но не рекомендуется вызывать этот метод напрямую, потому что иногда может быть, что объект имеет значение null или на объекте существует какое-либо свойство, например: { hasOwnProperty: false }
Итак, лучший способ:
// Good
var obj = {"bar": "here bar desc"}
console.info(Object.prototype.hasOwnProperty.call(obj, "bar"));
// Best
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.info(has.call(obj, "bar"));Не делайте этого object.hasOwnProperty(key)). Это действительно плохо, потому что эти методы могут быть затенены свойствами рассматриваемого объекта - рассмотрим { hasOwnProperty: false } - или объект может быть нулевым объектом (Object.create(null)).
Лучше всего сделать Object.prototype.hasOwnProperty.call(object, key) или:
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
/* Or */
import has from 'has'; // https://www.npmjs.com/package/has
// ...
console.info(has.call(object, key));
Я согласен с этим методом, и это должен быть принятый ответ, поскольку это самый безопасный способ при сохранении производительности! eslint.org/docs/rules/no-prototype-builtins говорит: «Например, для веб-сервера было бы небезопасно анализировать ввод JSON от клиента и вызывать hasOwnProperty непосредственно для полученного объекта, потому что злонамеренный клиент может отправить значение JSON, например {" hasOwnProperty ": 1}, и вызвать сервер разбиться ".
Не усложняйте вещи, когда вы можете:
var isProperty = (objectname.keyname || "") ? true : false;
Это просто и понятно для большинства случаев ...
Самый простой из них - var is Property = !! object name.key name;
Если объект имеет следующий вид const objectName = { keyname: false };, он должен вернуть true, поскольку keyname является свойством objectname. Но поскольку значение false, с этой логикой будет возвращено false.
Вы можете использовать следующие подходы:
var obj = {a:1}
console.info('a' in obj) // 1
console.info(obj.hasOwnProperty('a')) // 2
console.info(Boolean(obj.a)) // 3
Разница между следующими подходами заключается в следующем:
var obj = {
a: 2,
__proto__ : {b: 2}
}
console.info('b' in obj)
console.info(Boolean(obj.b))var obj = {
a: 2,
__proto__ : {b: 2}
}
console.info(obj.hasOwnProperty('b'))var obj = {
b : undefined
}
console.info(Boolean(obj.b))
console.info('b' in obj);Boolean({b:''}.b) -> false
@ KamilKiełczewski да, он должен давать false, любое ложное значение в этом случае вернет false
JavaScript сейчас развивается и растет, теперь у него есть хороший и лучший, даже эффективный способ его проверить.
Вот несколько простых способов проверить, есть ли объект имеет определенное свойство:
hasOwnProperty()const hero = {
name: 'Batman'
};
hero.hasOwnProperty('name'); // => true
hero.hasOwnProperty('realName'); // => false
inconst hero = {
name: 'Batman'
};
'name' in hero; // => true
'realName' in hero; // => false
undefinedconst hero = {
name: 'Batman'
};
hero.name; // => 'Batman'
hero.realName; // => undefined
// So consider this
hero.realName == undefined // => true (which means property does not exists in object)
hero.name == undefined // => false (which means that property exists in object)
Для получения дополнительной информации проверьте здесь.
Сегодня 2020.12.17 я провожу тесты на MacOs HighSierra 10.13.6 на Chrome v87, Safari v13.1.2 и Firefox v83 для выбранных решений.
Я сравниваю только решения A-F, потому что они дают верный результат для всех корпусов, используемых в разделе деталей фрагмента. Для всех браузеров
in (A) быстрое или самое быстроеhas (B) самое медленноеВыполняю 4 тестовых случая:
Во фрагменте ниже представлены различия между решениями. АBCDEFграммЧАСяJK
// SO https://stackoverflow.com/q/135448/860099
// src: https://stackoverflow.com/a/14664748/860099
function A(x) {
return 'key' in x
}
// src: https://stackoverflow.com/a/11315692/860099
function B(x) {
return _.has(x, 'key')
}
// src: https://stackoverflow.com/a/40266120/860099
function C(x) {
return Reflect.has( x, 'key')
}
// src: https://stackoverflow.com/q/135448/860099
function D(x) {
return x.hasOwnProperty('key')
}
// src: https://stackoverflow.com/a/11315692/860099
function E(x) {
return Object.prototype.hasOwnProperty.call(x, 'key')
}
// src: https://stackoverflow.com/a/136411/860099
function F(x) {
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
return hasOwnProperty(x,'key')
}
// src: https://stackoverflow.com/a/135568/860099
function G(x) {
return typeof(x.key) !== 'undefined'
}
// src: https://stackoverflow.com/a/22740939/860099
function H(x) {
return x.key !== undefined
}
// src: https://stackoverflow.com/a/38332171/860099
function I(x) {
return !!x.key
}
// src: https://stackoverflow.com/a/41184688/860099
function J(x) {
return !!x['key']
}
// src: https://stackoverflow.com/a/54196605/860099
function K(x) {
return Boolean(x.key)
}
// --------------------
// TEST
// --------------------
let x1 = {'key': 1};
let x2 = {'key': "1"};
let x3 = {'key': true};
let x4 = {'key': []};
let x5 = {'key': {}};
let x6 = {'key': ()=>{}};
let x7 = {'key': ''};
let x8 = {'key': 0};
let x9 = {'key': false};
let x10= {'key': undefined};
let x11= {'nokey': 1};
let b= x=> x ? 1:0;
console.info(' 1 2 3 4 5 6 7 8 9 10 11');
[A,B,C,D,E,F,G,H,I,J,K ].map(f=> {
console.info(
`${f.name} ${b(f(x1))} ${b(f(x2))} ${b(f(x3))} ${b(f(x4))} ${b(f(x5))} ${b(f(x6))} ${b(f(x7))} ${b(f(x8))} ${b(f(x9))} ${b(f(x10))} ${b(f(x11))} `
)})
console.info('\nLegend: Columns (cases)');
console.info('1. key = 1 ');
console.info('2. key = "1" ');
console.info('3. key = true ');
console.info('4. key = [] ');
console.info('5. key = {} ');
console.info('6. key = ()=>{} ');
console.info('7. key = "" ');
console.info('8. key = 0 ');
console.info('9. key = false ');
console.info('10. key = undefined ');
console.info('11. no-key ');<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity = "sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww= = " crossorigin = "anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!А вот примеры результатов для хрома
Если вы хотите перебрать свойства объекта без использования проверки hasOwnProperty(),
используйте метод for(let key of Object.keys(stud)){}:
for(let key of Object.keys(stud)){
console.info(key); // will only log object's Own properties
}
полный Пример и сравнение с for-in with hasOwnProperty()
function Student() {
this.name = "nitin";
}
Student.prototype = {
grade: 'A'
}
let stud = new Student();
// for-in approach
for(let key in stud){
if (stud.hasOwnProperty(key)){
console.info(key); // only outputs "name"
}
}
//Object.keys() approach
for(let key of Object.keys(stud)){
console.info(key);
}
Показано, как использовать этот ответ
const object= {key1: 'data', key2: 'data2'};
Object.keys(object).includes('key1') //returns true
Мы также можем использовать indexOf, я предпочитаю включает в себя
Я написал тест jsperf со всеми ответами, чтобы узнать, какой из них самый быстрый: jsperf.com/dictionary-contains-key