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

时间:2020-03-06 14:44:37  来源:igfitidea点击:

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

考虑:

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

那是最好的方法吗?

解决方案

是的,这是:)我想我们也可以执行Object.prototype.hasOwnProperty.call(x,'key'),如果x具有名为" hasOwnProperty` :)的属性,它也应该可以工作。

但这会测试自己的属性。如果要检查它是否具有可以继承的属性,可以使用typeof x.foo!='undefined'

if (x.key !== undefined)

Armin Ronacher似乎已经击败了我,但是:

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

Konrad Rudolph和Armin Ronacher指出,一种更安全但较慢的解决方案是:

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

好的,除非我们不需要继承的属性,否则我的回答似乎正确:

if (x.hasOwnProperty('key'))

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

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

if (x.key !== undefined)

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

}

因为

if (x.key)

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

注意:由于严格模式和" hasOwnProperty",以下内容如今已过时。正确的解决方案是使用严格模式,并使用obj.hasOwnProperty检查属性是否存在。这个答案早于这两件事,至少已经得到了广泛的应用(是的,它已经很老了)。将以下内容作为历史记录。

请记住,不幸的是,如果我们未使用严格模式,则" undefined"不是JavaScript中的保留字。因此,某个人(显然是其他人)可能有重新定义它的宏大想法,从而破坏了代码。

因此,一种更可靠的方法如下:

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

另一方面,这种方法比较冗长,而且速度较慢。 :-/

一种常见的替代方法是确保undefined实际上是未定义的,例如通过将代码放入一个函数中,该函数接受一个名为" undefined"的添加参数,该参数未传递值。为确保其未传递值,我们可以立即自行调用它,例如:

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

我对大多数给出的答案完全是完全错误的感到困惑。当然,我们可以拥有具有未定义,空值或者假值的对象属性。因此,简单地将属性检查减少为" typeof this [property]",甚至更糟糕的是,将" x.key"减少到完全误导结果。

这取决于我们要查找的内容。如果我们想知道一个对象是否物理上包含一个属性(它不是来自原型链上的某个地方),那么可以使用object.hasOwnProperty。所有现代的浏览器都支持它。 (在旧版的Safari 2.0.1和旧版的Safari中是缺少的,但很少再使用这些版本的浏览器。)

如果我们要查找的是对象上具有可迭代的属性(当我们遍历该对象的属性时,它将出现),则可以这样做:" 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"的一种跨浏览器的工作解决方案,但有一个警告:无法区分原型上具有相同属性的情况和实例上仅假设属性来自原型的情况。我们可以根据自己的情况将其更改为宽容或者严格,但是至少这应该会有所帮助。

让我们在这里消除一些困惑。首先,我们假设" hasOwnProperty"已经存在,以进行简化。当前使用的绝大多数浏览器都是如此。

如果已将传递给它的属性名称添加到对象,则" hasOwnProperty"将返回true。它完全独立于分配给它的实际值,而实际值可能是"未定义"的。

因此:

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"仍会在枚举中列出。

最重要的是,没有跨浏览器的方法(因为InternetExplorer不公开__prototype__)来确定特定的标识符尚未添加到对象或者其原​​型链中的任何内容。