Как проверить, есть ли у объекта определенное свойство в JavaScript?

Как проверить, есть ли у объекта определенное свойство в JavaScript?

Рассматривать:

x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
    //Do this
}

Это лучший способ сделать это?

Я написал тест jsperf со всеми ответами, чтобы узнать, какой из них самый быстрый: jsperf.com/dictionary-contains-key

styfle 10.03.2016 19:36

('propertyName' в объекте)? 'property is there': 'свойство is not there'

Mohan Ram 05.10.2018 12:08

@styfle спасибо за тест jsperf. in и hasOwnProperty вышли на путь медленнее, чем другие для меня (на 98% медленнее). Я не удивлен тем, что hasOwnProperty работает медленнее, но меня удивляет in.

evanrmurphy 16.11.2018 23:16
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1 591
3
1 086 240
27
Перейти к ответу Данный вопрос помечен как решенный

Ответы 27

Да, это так :) Я думаю, вы также можете сделать 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;

Joe Simmons 28.09.2013 11:28

Не просить не соглашаться, а понимать. Есть ли точка, в которой x.hasOwnProperty вернет что-либо, кроме логического значения true или false? Если нет, то опубликованный код должен работать каждый раз. Я полагаю, возможно, если бы метод был переопределен, но тогда полагаться на результат никогда не было бы надежным, если вы не знаете метод переопределения.

enobrev 29.09.2013 19:47

Я думаю, у нас недопонимание. Я имею в виду, что, используя ваш метод, он скажет, что toString - это собственное свойство, но это не так.

Joe Simmons 30.09.2013 05:38

Object.prototype уже имеет встроенный правильный hasOwnProperty. Перезапись его неправильной реализацией (1. Свойства могут иметь значение undefined, 2. Это приведет к ложным срабатываниям для унаследованных свойств) - просто ужасно плохая идея. Неправильные ответы можно и нужно удалять. Я не знаю, могли бы вы сделать это в сентябре 2008 г. когда вы увидели ответ Ресига, поэтому комментирую, чтобы предложить сделать это сейчас.

T.J. Crowder 18.09.2016 11:10

Хорошо, похоже, я получил правильный ответ, если только вы не хотите унаследованные свойства:

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 не истинно.

AnthonyWJones 26.09.2008 12:34

Для var x = { key: false }; метод x.key будет неправильным.

Mark K Cowan 20.10.2014 13:37

если (x.key) неверен, как если бы x = {key: 0}, он не пройдет проверку.

someUser 19.09.2016 11:40

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.

Wilt 17.10.2019 12:02

Примечание: следующее в настоящее время в значительной степени устарело благодаря строгому режиму и 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?

Brian M. Hunt 01.02.2013 21:01

Брайан: Я не эксперт, но это кажется отличным способом сделать все правильно.

Christopher Smith 26.02.2013 02:29

Если бы знаменитый «кто-то другой» изменил определение undefined, я думаю, что лучше всего было бы переписать ЭТО код.

Oskar Holmkratz 18.05.2013 22:00

undefined = (function () {}()); if (a.attribute !== undefined) 'foo';

Joe Simmons 30.09.2013 05:40

Лучше всего иметь твердую неопределенную переменную, работать в замыкании и иметь непревзойденную сигнатуру функции: (function (undefined) { // undefined is actually undefined here })();

bgusach 15.10.2013 14:20

Начиная со строгого режима ES5, вы больше не можете переопределить undefined, но вам нужно не забыть включить строгий режим. :) Кроме того, этот ответ не проверяет, есть ли у объекта какое-либо свойство, а проверяет, является ли свойство неопределенным (включая как существующие, так и несуществующие свойства).

user234932 09.12.2016 23:50

@ BrianM: Ваше предложение с x.attribute !== void 0 (или void(0)) отлично работает в моем тесте.

evanrmurphy 16.11.2018 23:19

@evanrmurphy Не используйте это, это серьезно устарело (см. примечание в начале моего ответа).

Konrad Rudolph 17.11.2018 16:19
Ответ принят как подходящий

Меня действительно сбивают с толку полученные ответы - большинство из них совершенно неверны. Конечно, у вас могут быть свойства объекта с неопределенными, нулевыми или ложными значениями. Таким образом, простое сокращение проверки собственности до 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;. Но если вы занимаетесь чем-то вроде библиотеки, вам, возможно, придется пойти немного дальше в некоторых частях.

Halil Özgür 22.02.2011 19:28

@ kralco626: Да, в настоящее время я считаю, что использовать hasOwnProperty () довольно безопасно, но для действительно безопасного кросс-браузерного решения используйте John's.

Jacob 10.01.2012 17:28

А как насчет изменения временный__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).

average Joe 17.12.2012 14:06

@Kasztan __proto__ нестандартен и не работает в некоторых старых браузерах. И даже с недавним добавлением Object.getPrototypeOf стандарт говорит, что вы все еще не можете изменить прототип существующего объекта.

Matt Browne 25.02.2013 23:11

Ответы Джона Ресига, похоже, не работают в 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/…

Adrien Be 14.10.2014 14:43

Цикл for(prop in object) выполняет итерацию только по перечислимым свойствам. Однако prop in object проверяет, имеет ли object свойство prop где-нибудь в цепочке прототипов, независимо от того, перечислимо ли оно или нет.

Oriol 06.01.2016 02:27

В качестве примечания к функциям, объявленным внутри if, это работает во всех известных мне современных браузерах, но не поддерживается PhantomJS.

Aardvark 30.09.2016 22:17

Поскольку ECMA Script Version 6 включает функцию Reflect, это предпочтительный путь. У него есть has () и get (), что позволяет очень легко создать оболочку для получения Safe-Arguments. Не все браузеры могут поддерживать эту функцию (не в IE и Opera), но скоро это изменится. Используйте ECMA «использовать версию 6», чтобы обеспечить правильную версию скрипта.

Harm 19.12.2016 13:46

Предупреждение: не используйте проверку in для примитивов.

S.D. 02.09.2020 23:08

Давайте прорежем здесь некоторую путаницу. Во-первых, давайте упростим, предположив, что 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».

Winfield Trail 04.09.2014 23:15

Я понимаю вашу точку зрения, @sudowned, спасибо. Между прочим, если бы кто-то не хотел включать всю библиотеку lodash, можно было бы скомпилировать подкомпоненты или npm install lodash.has, который предоставляет модуль npm только с функцией has, которая компилируется до 175 байт при минификации. Также полезно взглянуть на lodash.has/index.js, чтобы увидеть, как работает очень популярная и надежная библиотека.

Brian M. Hunt 04.09.2014 23:41

и версии lodash работают с этим: .has(undefined, 'someKey') => false, а underscore возвращает undefined

Brad Parks 10.09.2014 15:06

Спасибо @BradParks - я на самом деле не смотрел документацию для версии underscore, поэтому я уверен, что это может быть полезно для тех, кто это читает.

Brian M. Hunt 10.09.2014 17:29

Спасибо @ brian-m-hunt. Я уже включил lodash, начал поиски еще до того, как должен был стать RTFM.

Paul J 17.03.2015 01:18

Я не верю, что использование библиотеки является приемлемым ответом, потому что вопрос задается «в JavaScript», а не «с использованием библиотеки JavaScript».

Dave 19.04.2016 22:59

Всем, кто жалуется на добавление lodash в качестве «еще одной» зависимости: это довольно распространенная (если не самая распространенная) библиотека для такого рода вещей. Удачи, изобретая велосипед.

Priidu Neemre 18.11.2016 15:37

Даже если вы хотите изобрести колесо, проверка существующих колес - неплохая идея.

AturSams 25.04.2017 14:53

Кроме того, OP, возможно, даже не знал об этом. Поэтому слова «в JavaScript» или «с JQuery» не означают, что они не открыты для новых библиотек, о существовании которых они, возможно, не знали, и просто пытались использовать базовый Javascript или JQuery, потому что думали, что это все, что у них было в распоряжении для это. Но выбранный ответ, в котором упоминается использование hasOwnProperty, является самым простым способом сделать это.

Tyler Dahle 22.06.2017 18:31

Ради любви к Богу используйте Lodash или любую другую доступную библиотеку, пока JS не разберется со своей красивой, мелкой головкой. По крайней мере, если вы пойдете по этому пути, вы избавитесь от смехотворного количества прыжков через кольцо для совместимости с браузером. Проблема решена. Двигаться дальше.

Damien Roche 10.10.2018 09:25

Преимущество _.has в том, что вы можете использовать точечную нотацию для проверки глубоко вложенных атрибутов, например _.has (myObject, 'a.b.c');

omarjebari 30.06.2020 15:52

Использовать:

var x = {
  'key': 1
};

if ('key' in x) {
  console.info('has');
}

Следует отметить, что он работает с «объектами» в узком смысле, поэтому, объявленный как {} или созданный с помощью конструктора, он не принимает массивы или примитивы. Не то чтобы OP этого требовал, но в некоторых других ответах представлены более широкие методы (работа с массивами, строками и т. д.)

Danubian Sailor 27.08.2014 16:22

@ РСТȢѸФХѾЦЧШЩЪЫЬѢѤЮѦѪѨѬѠѺѮѰѲѴ спасибо, что указали на это (принятый ответ не содержит подробностей о том, почему следует использовать оператор in или нет. Также обратите внимание, что оператор in имеет отличную поддержку браузера IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+stackoverflow.com/questions/2920765/…

Adrien Be 15.10.2014 11:42

Оператор in также проверяет свойства прототипа, тогда как hasOwnProperty выполняет итерацию только по свойствам, определенным пользователем. Ссылка: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

adi518 09.07.2016 14:57

'key' in xделать работает с массивами. Доказательство: stackoverflow.com/questions/33592385/…

CosmoMyzrailGorynych 05.01.2017 04:54

Кажется, лучший и самый короткий вариант

user365314 05.01.2020 17:43

Если вы ищете недвижимость, тогда "нет". Вы хотите:

if ('prop' in obj) { }

В общем, вам не нужно беспокоиться о том, исходит ли свойство от прототипа или объекта.

Однако, поскольку вы использовали «ключ» в образце кода, похоже, что вы обрабатываете объект как хэш, и в этом случае ваш ответ будет иметь смысл. Все ключи хэшей будут свойствами объекта, и вы избегаете дополнительных свойств, вносимых прототипом.

Ответ Джона Ресига был очень подробным, но я думал, что это не совсем понятно. Особенно, когда использовать "'prop' в obj".

Отметим, что оператор in имеет отличную поддержку браузера IE 5.5+, Chrome 1.0+, Firefox 1.0+, Safari 3.0+stackoverflow.com/questions/2920765/…

Adrien Be 15.10.2014 11:38

Как указано в другом комментарии относительно использования оператора in: «он работает с« объектами »в узком смысле, поэтому объявлен как {} или создан с помощью конструктора, он не принимает массивы или примитивы. Не то, чтобы OP этого требовал, но в некоторых других ответах представлены более широкие методы (работа с массивами, строками и т. д.) "

Adrien Be 15.10.2014 11:44

Комментируя причину, меня дважды отвергали без комментариев. Но мне все равно нравится мой ответ. Возможно, тот, кто это сделал, хотел получить «исчерпывающий» ответ для всех способов тестирования всех типов свойств .. Но мой ответ концептуален и поэтому краток. Re: Адриен Бе, неисчислимое свойство - это свойство, которое не предназначено для общей пользовательской области, поэтому концептуально 'in' в порядке;)

Gerard ONeill 27.11.2017 20:36

Вы можете использовать оператор 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? Кроме, конечно, доступа к массиву ..

Gerard ONeill 25.08.2014 22:35

Другой относительно простой способ - использовать 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.

Victorio Berra 26.10.2015 19:40

Тогда вы бы сделали Object.keys(info).indexOf('someotherthing') !== -1

hippietrail 15.06.2016 07:18

Что такое "JS v1.8.5"? «JavaScript v1.8.5» *? Похоже, он не соответствует ни одной версии ECMAScript (версия 8 была выпущена в 2017 году). jQuery 1.8 был выпущен в 2012 году.

Peter Mortensen 06.10.2020 19:24

Хорошо, JavaScript 1.8.5 был выпущен в 2011 году вместе с Firefox 4 (2011-03-22). Первая версия ECMAScript 5 (связанная с) относится к 2009 году.

Peter Mortensen 06.10.2020 19:53

hasOwnProperty «может использоваться, чтобы определить, имеет ли объект указанное свойство как прямое свойство этого объекта; в отличие от оператора in, этот метод не проверяет цепочку прототипов объекта».

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

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

if (prop in object) { // Do something }

Я получаю сообщение «Невозможно использовать оператор 'in' для поиска 'prop' в myObject»

Victorio Berra 26.10.2015 19:42

Вот еще один вариант для конкретного случая. :)

Если вы хотите протестировать член объекта и хотите узнать, установлено ли для него что-то иное, кроме:

  • ''
  • ложный
  • нулевой
  • неопределенный
  • 0 ...

тогда вы можете использовать:

var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
    // member is set, do something
}

Компактный и удобный

Frederik Witte 26.07.2019 15:41

Линтеру это не понравится: eslint.org/docs/rules/no-extra-boolean-cast

Wilt 17.10.2019 11:47

Вы также можете использовать объект 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?

hippietrail 30.08.2017 07:36

Имхо, это самый короткий и простой ответ, но, возможно, не самый быстрый в исполнении кода. Но скорость (больше) не проблема.

Harm 31.08.2017 17:20

Зачем дважды размещать Такой же ответ? Вы можете просто проголосовать за существующую ...?

Wilt 19.11.2020 22:15

Вам нужно использовать метод 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}, и вызвать сервер разбиться ".

Arman 07.10.2019 02:24

Не усложняйте вещи, когда вы можете:

var isProperty =  (objectname.keyname || "") ? true : false;

Это просто и понятно для большинства случаев ...

Самый простой из них - var is Property = !! object name.key name;

John 24.01.2019 10:04

Если объект имеет следующий вид const objectName = { keyname: false };, он должен вернуть true, поскольку keyname является свойством objectname. Но поскольку значение false, с этой логикой будет возвращено false.

Wilt 17.10.2019 11:53

Вы можете использовать следующие подходы:

var obj = {a:1}
console.info('a' in obj)               // 1
console.info(obj.hasOwnProperty('a'))  // 2
console.info(Boolean(obj.a))         // 3

Разница между следующими подходами заключается в следующем:

  1. В первом и третьем подходах мы ищем не только объект, но и его прототипную цепочку. Если у объекта нет свойства, но свойство присутствует в его цепочке прототипов, оно будет иметь значение true.

var obj = {
    a: 2,
    __proto__ : {b: 2}
}

console.info('b' in obj)
console.info(Boolean(obj.b))
  1. Второй подход будет проверять только его собственные свойства. Пример -

var obj = {
    a: 2,
    __proto__ : {b: 2}
}

console.info(obj.hasOwnProperty('b'))
  1. Разница между первым и третьим заключается в том, что если есть свойство со значением undefined, третий подход даст false, а первый вернет.

var obj = {
    b : undefined
}

console.info(Boolean(obj.b))
console.info('b' in obj);

Boolean({b:''}.b) -> false

Kamil Kiełczewski 15.12.2020 23:29

@ KamilKiełczewski да, он должен давать false, любое ложное значение в этом случае вернет false

Komal Bansal 16.12.2020 07:56

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

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

  1. Использование hasOwnProperty()
const hero = {
  name: 'Batman'
};

hero.hasOwnProperty('name');     // => true
hero.hasOwnProperty('realName'); // => false
  1. Использование ключевого слова / оператора in
const hero = {
  name: 'Batman'
};

'name' in hero;     // => true
'realName' in hero; // => false
  1. Сравнение с ключевым словом undefined
const 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) быстрое или самое быстрое
  • решение (E) является самым быстрым для Chrome для больших объектов и самым быстрым для Firefox для небольших массивов, если ключ не существует
  • решение (F) является самым быстрым (~> 10x, чем другие решения) для небольших массивов
  • решения (D, E) довольно быстрые
  • решение на базе losash has (B) самое медленное

Подробности

Выполняю 4 тестовых случая:

  • когда у объекта 10 полей и существует искомый ключ - его можно запустить ЗДЕСЬ
  • когда объект имеет 10 полей и искомого ключа не существует - вы можете запустить его ЗДЕСЬ
  • когда у объекта 10000 полей и существует искомый ключ - вы можете запустить его ЗДЕСЬ
  • когда у объекта 10000 полей и существует искомый ключ - вы можете запустить его ЗДЕСЬ

Во фрагменте ниже представлены различия между решениями. А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, я предпочитаю включает в себя

Другие вопросы по теме