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



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



считаем:



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


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

355   23  

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 как:

   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 и на самом деле 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 петли. Кроме того, если перечисляемое свойство затеняет не перечисляемое свойство прототипа, он не будет отображаться в 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

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

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

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

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

  • "
  • ложные
  • 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" существует на объекте, но его не рекомендуется вызывать этот метод напрямую, потому что иногда объект может быть null или некоторые свойства существуют на объекте, как:{ 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");
}

Comments

    Ничего не найдено.