首页 文章

如何检查对象在JavaScript中是否具有属性?

提问于
浏览
1237

如何检查对象在JavaScript中是否具有属性?

考虑:

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

这是最好的方法吗?

23 回答

  • 248

    假设 hasOwnProperty 已存在,让's cut through some confusion here. First, let'简化;对于当前使用的绝大多数浏览器来说都是如此 .

    如果传递给它的属性名称已添加到对象, hasOwnProperty 将返回true . 它完全独立于分配给它的实际值,可能正好是 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
    

    问题是当原型链中的对象具有值为undefined的属性时会发生什么? hasOwnProperty 将为false, !== undefined 也是如此 . 然而, for..in 仍然会在枚举中列出它 .

    底线是没有跨浏览器方式(因为Internet Explorer不公开 __prototype__ )以确定特定标识符尚未附加到对象或其原型链中的任何内容 .

  • 37

    您需要使用方法 object.hasOwnProperty(property) . 如果对象具有属性,则返回true;如果对象不具有该属性,则返回false .

  • 16

    不要这样做 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.log(has.call(object, key));
    
  • 32

    你也可以使用the ES6 Reflect object

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

    有关 Reflect.has 的MDN文档可以在here找到 .

    静态Reflect.has()方法与in运算符的作用类似 .

  • 2

    对象上存在方法"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"));
    
  • 10

    hasOwnProperty“可用于确定对象是否具有指定的属性作为该对象的直接属性; unlike the in operator ,此方法不会检查对象的原型链 . ”

    所以很可能,对于你的问题看来,你不想使用hasOwnProperty,它决定了属性是否作为附加 directly to the object itself 存在 .

    如果你想确定你想要使用的原型链中是否存在该属性,例如:

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

    我希望这有帮助 .

  • 8

    由于存在大规模贬值的风险,这是特定案例的另一种选择 . :)

    如果要测试对象上的成员并想知道它是否已设置为以下内容:

    • ''

    • null

    • undefined

    • 0 ......

    然后你可以使用:

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

    为什么你可以做的事情过于复杂:

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

    大多数情况下简单明了......

  • 12

    我对所给出的答案感到困惑 - 大多数答案都是完全不正确的 . 当然,您可以拥有具有undefined,null或false值的对象属性 . 因此,简单地将属性检查减少到 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 解决方案,但有一点需要注意:它无法区分原型和实例上相同属性的情况 - 它只是假设它来自原型 . 根据你的情况,你可以把它转移到更宽松或更严格的程度,但至少这应该更有帮助 .

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

    因为

    if (x.key)
    

    如果 x.key 解析为 false (例如, x.key = "" ),则会失败 .

  • 1

    另一种相对简单的方法是使用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起这是安全的

  • 5

    如果您要检查的密钥存储在变量中,您可以这样检查:

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

    我用过这个 . 如果你在对象里面有一个对象,这对我很有帮助

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

    Note :由于严格模式,以下现在基本上已经过时了, hasOwnProperty . 正确的解决方案是使用严格模式并使用 obj.hasOwnProperty 检查属性是否存在 . 这个答案早于这两个方面,至少同样广泛实施(是的,它是旧的) . 请将以下内容作为历史记录 .


    请记住,如果您没有使用严格模式, undefined (遗憾的是)不是JavaScript中的保留字 . 因此,某人(显然是其他人)可能会有重新定义它的宏伟想法,破坏您的代码 .

    因此,更强大的方法如下:

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

    另一方面,这种方法更冗长,也更慢 . : - /

    一种常见的替代方法是确保 undefined 实际上是未定义的,例如将代码放入一个函数中,该函数接受一个名为 undefined 的附加参数,该函数不传递值 . 为了确保它没有传递一个值,你可以立即自己调用它,例如:

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

    Armin Ronacher似乎已经beat me to it,但是:

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

    一个更安全但更慢的解决方案as pointed out by Konrad RudolphArmin Ronacher将是:

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

    好的,看起来我有正确的答案,除非你不想要继承的属性:

    if (x.hasOwnProperty('key'))
    

    以下是包含继承属性的其他一些选项:

    if (x.key) // Quick and dirty, but it does the same thing as below.
    
    if (x.key !== undefined)
    
  • 6

    如果您正在寻找房产,那么“不” . 你要:

    if ('prop' in obj) { }
    

    通常,您不应该关心属性是来自原型还是对象 .

    但是,因为您在示例代码中使用了“key”,所以看起来您将对象视为哈希,在这种情况下,您的答案是有意义的 . 所有哈希键都是对象中的属性,并且您可以避免原型提供的额外属性 .

    John Resig的回答非常全面,但我认为还不清楚 . 特别是何时在obj中使用“'prop'” .

  • 0

    您可以使用 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 . 否则它将返回适当的属性类型 . 但是,请注意,这并不总是检查对象是否具有属性的有效方法,因为您可以将属性设置为undefined,在这种情况下,使用 typeof x.key 仍将返回true(即使键是仍在对象中) .

    更新:您可以通过与未定义的javascript属性进行比较来检查属性是否存在

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

    除非在x对象上专门设置为 undefined ,否则这应该有效

  • 25

    使用Underscore.js或(even betterlodash

    _.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
    
  • 2

    关于什么?

    var x = {'key': 1};
    
    if ('key' in x) {
        console.log('has');
    }
    
  • 1

    要测试简单对象,请使用: if (obj[x] !== undefined)

    如果您不知道它使用的是哪种对象类型: if (obj.hasOwnProperty(x))

    所有其他选项都比较慢..

    Details

    在Nodejs下的100,000,000个周期的性能评估到其他人建议的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)... It is between 2 to 6 times slower depending on the use case

    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])... ,因为我发现它更具可读性 .

    玩得开心 .

  • 2

    是的它是:)我认为你也可以做 Object.prototype.hasOwnProperty.call(x, 'key') 如果 x 有一个名为 hasOwnProperty 的属性也应该工作

    但是那可以测试自己的属性 . 如果要检查它是否具有可能已被连接的属性,则可以使用 typeof x.foo != 'undefined' .

  • -1

    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
    

相关问题