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

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

считаем:

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

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

23 ответов


Я не понимаю ответы, которые были даны - большинство из них просто откровенно неверны. Конечно, у вас могут быть свойства объекта с неопределенными, нулевыми или ложными значениями. Поэтому просто уменьшите проверку свойства до 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, С одним предостережением: он не может различать случаи, когда одинаковое свойство находится на прототипе и на экземпляре - он просто предполагает, что оно исходит от прототипа. Вы можете изменить его на более мягкий или строгий, исходя из вашей ситуации, но, по крайней мере, это должно быть более полезным.


С Underscore.js или (еще лучше) lodash:

_.has(x, 'key');

которых звонки Object.prototype.hasOwnProperty, но (a) короче для ввода и (b) использует "безопасную ссылку на hasOwnProperty" (т. е. он работает, даже если hasOwnProperty перезаписывается).

в частности, лодаш определяет _.has as:

   function has(object, key) {
      return object ? hasOwnProperty.call(object, key) : false;
   }
   // hasOwnProperty = Object.prototype.hasOwnProperty

Примечание: следующее В настоящее время в значительной степени устарело благодаря строгому режиму и hasOwnProperty. Правильное решение - использовать строгий режим и проверять наличие свойства с помощью obj.hasOwnProperty. Этот ответ до обе эти вещи, по крайней мере, так широко реализованы (да, это старый). Возьмите следующее в качестве исторической заметки.


имейте в виду, что undefined это (к сожалению) не зарезервированное слово в JavaScript, если вы не используете строгий режим. Поэтому у кого-то (очевидно, у кого-то другого) может возникнуть грандиозная идея переопределить его, нарушив ваш код.

поэтому более надежный метод заключается в следующем:

if (typeof(x.attribute) !== 'undefined')

С другой стороны, этот метод гораздо более подробный, а также медленнее. :-/

общей альтернативой является обеспечение того, что undefined is на самом деле undefined, например, путем ввода кода в функцию, которая принимает дополнительный параметр, называется undefined, это не передается значение. Чтобы убедиться, что он не передал значение, вы можете сразу же вызвать его, например:

(function (undefined) {
    … your code …
    if (x.attribute !== undefined)
        … mode code …
})();

о чем?

var x = {'key': 1};

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

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!');
}

безопаснее, но медленнее решением как указал by Конрад Рудольф и Армин Ронахер будет:

Object.prototype.hasOwnProperty = function(property) {
    return typeof this[property] !== 'undefined';
};

можно использовать in оператор, чтобы проверить, существует ли свойство на объекте:

x = {'key': 1};
alert("key" in x);

вы также можете просмотреть все свойства объекта, используя for - in цикл, а затем проверьте конкретное свойство:

for (prop in x) {
    if (prop == "key") {
        //Do something
    }
}

вы должны учитывать, является ли это свойство объекта перечисляемым или нет, потому что не перечисляемые свойства не будут отображаться в for-in петли. Кроме того, если свойство enumerable затеняет свойство без перечисления прототипа, он не будет отображаться в Internet Explorer 8 и ранее.

если вам нужен список всех свойств экземпляра, перечислимых или нет, вы можете использовать

Object.getOwnPropertyNames(x);

возвращает массив имен всех свойств, которые существуют на объекте.

наконец, вы можете использовать оператор typeof для прямой проверки типа данных свойства объекта:

if (typeof x.key == "undefined") {
    alert("undefined");
}

если свойство не существует на объекте, оно вернет строка не определена. В противном случае он вернет соответствующий тип свойства. Однако обратите внимание, что это не всегда допустимый способ проверки, имеет ли объект свойство или нет, потому что у вас может быть свойство, которое имеет значение undefined, в этом случае, используя typeof x.key все равно вернет true (даже если ключ все еще находится в объекте).

Update: вы можете проверить, существует ли свойство, сравнивая с неопределенным свойством javascript

if (x.key === undefined) {
    alert("undefined");
}

это должно работать, если ключ специально для undefined на объекте x


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

hasOwnProperty возвращает true, если имя атрибута, переданное ему, было добавлено к объекту. Это совершенно не зависит от фактического значения, которое может быть точно 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

проблема в том, что происходит, когда объект в цепочке прототипов имеет атрибут со значением неопределено? hasOwnProperty будет ложным для него, и так будет !== undefined. Однако, for..in по-прежнему будет перечислять его в перечислении.

суть в том ,что нет кросс-браузера (поскольку Internet Explorer не выставляет __prototype__), чтобы определить, что идентификатор не был прикреплен к объекту или что-то в его цепочке прототипов.


Если вы ищете свойство, то "нет". Вы хотите:

if ('prop' in obj) { }

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

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

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


Да, это:) я думаю, вы также можете сделать Object.prototype.hasOwnProperty.call(x, 'key') который также должен работать, если x имеет свойство с именем hasOwnProperty :)

но это проверяет собственные свойства. Если вы хотите проверить, имеет ли он свойство, которое также может быть inhered вы можете использовать typeof x.foo != 'undefined'.


if (typeof x.key != "undefined") {

}

, потому что

if (x.key)

, если не x.key разрешает false (например, x.key = "").


вы также можете использовать в ЕС6 Reflect объект:

x = {'key': 1};
Reflect.has( x, 'key'); // returns true

документация по MDN для Reflect.has можно найти здесь.

статический!--3--> метод работает как в оператора как функция.


для тестирования простых объектов используйте: if (obj[x] !== undefined)

если вы не знаете, какой тип объекта он использует: if (obj.hasOwnProperty(x))

все остальные параметры медленнее..

подробности

оценка производительности 100,000,000 циклов под Nodejs до 5 вариантов, предложенных другими здесь:

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: 4s 510.427785ms
hasKey2 execution time: 0s 904.374806ms
hasKey3 execution time: 0s 760.336193ms
hasKey4 execution time: 0s 935.19901ms
hasKey5 execution time: 2s 148.189608ms

итог, если ваш Obj не обязательно является простым объектом, и вы хотите избежать проверки цепочки прототипов объекта и убедиться, что x принадлежит Obj напрямую, используйте ' if (obj.hasOwnProperty (x))...'.

в противном случае, при использовании простого объекта и не беспокоясь о цепочке прототипов объекта, используя if (typeof(obj[x]) !== 'undefined')... самый безопасный и быстрый способ.

если вы используете простой объект в качестве хэш-таблицы и никогда не делаете ничего странного, я бы использовал if (obj[x])... как я нахожу его гораздо более читаемым.

получать удовольствие.


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

if (x.hasOwnProperty('key'))

вот некоторые другие параметры для включения унаследованных свойств:

if (x.key) // Quick and dirty, but it does the same thing as below.

if (x.key !== undefined)

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

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

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

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

надеюсь, это поможет.


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

хотя мы живем в мире с большой поддержкой браузера. Потому что этот вопрос такой старый, что я решил добавить это.: Это безопасно для использования с JS v1.8.5


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

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

  • "
  • false
  • null
  • неопределено
  • 0 ...

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

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

ECMA Script 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

существует метод "hasOwnProperty" существует на объекте, но его не рекомендуется вызывать этот метод напрямую, потому что иногда объект может быть нулевым или какое-то свойство существует на объекте, например: { hasOwnProperty: false }

Так что лучший способ будет:

// good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));

// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));

не делайте этого object.hasOwnProperty(key)), это действительно плохо, потому что эти методы могут быть затенены свойствами рассматриваемого объекта-рассмотрим { hasOwnProperty: false } - или объект может быть null объект (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.log(has.call(object, key));

вам нужно использовать метод object.hasOwnProperty(property). Она возвращает true, если объект имеет свойство, и false, если объект не имеет.


Если ключа проверки хранится в переменная, вы можете проверить это так:

x = {'key': 1};
y = 'key';
x[y];

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

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

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


я использовал это. что очень помогло мне, если у вас есть объекты внутри объекта

if(typeof(obj["key"])=="string"){
    alert("property");
}