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


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

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

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

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


1169


источник


Ответы:


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


1190



С Underscore.jsили ( даже лучше ) lodash:

_.has(x, 'key');

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

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

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

234



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


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

Таким образом, более надежный метод заключается в следующем:

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

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

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

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

101



Как насчет?

var x = {'key': 1};

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

90



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

35



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

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

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

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

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

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

Object.getOwnPropertyNames(x);

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

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

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

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

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

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

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


30



Let's cut through some confusion here. First, let's simplify by assuming hasOwnProperty already exists; this is true of the vast majority of current browsers in use.

hasOwnProperty returns true if the attribute name that is passed to it has been added to the object. It is entirely independent of the actual value assigned to it which may be exactly undefined.

Hence:

var o = {}
o.x = undefined

var a = o.hasOwnProperty('x')  // a is true
var b = o.x === undefined // b is also true

However:

var o = {}

var a = o.hasOwnProperty('x')  // a is now false
var b = o.x === undefined // b is still true

The problem is what happens when an object in the prototype chain has an attribute with the value of undefined? hasOwnProperty will be false for it, and so will !== undefined. Yet, for..in will still list it in the enumeration.

The bottom line is there is no cross-browser way (since Internet Explorer doesn't expose __prototype__) to determine that a specific identifier has not been attached to an object or anything in its prototype chain.


20



If you are searching for a property, then "NO". You want:

if ('prop' in obj) { }

In general you should not care whether or not the property comes from the prototype or the object.

However, because you used 'key' in your sample code, it looks like you are treating the object as a hash, in which case your answer would make sense. All of the hashes keys would be properties in the object, and you avoid the extra properties contributed by the prototype.

John Resig's answer was very comprehensive, but I thought it wasn't clear. Especially with when to use "'prop' in obj".


14



Yes it is :) I think you can also do Object.prototype.hasOwnProperty.call(x, 'key') which should also work if x has a property called hasOwnProperty :)

But that tests for own properties. If you want to check if it has an property that may also be inhered you can use typeof x.foo != 'undefined'.


12