当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何检查对象是否在JavaScript中具有属性?》经验,为你挑选了16个好方法。

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

考虑:

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

这是最好的方法吗?



1> John Resig..:

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


`for(prop in object)`循环只迭代可枚举的属性.然而,`object in object`检查`object`是否在原型链中的某处具有属性`prop`,独立于是否可枚举.
@grantwparks如果您正在构建一个简单的滑块插件并想要检查选项项是否存在,那么这可能不仅仅是需要.你可以做一些像`var w = opts.w ||这样的事情 100;`.但是,如果你是某种类似的东西,你可能需要在某些部分更进一步.
@Kasztan`__proto__`是非标准的,在某些较旧的浏览器中不起作用。即使最近添加了“ Object.getPrototypeOf”,该标准仍说您仍然无法更改现有对象的原型。

2> Brian M. Hun..:

使用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


我猜它是因为"添加这个库"很少是一个流行的解决方案,即使问题是复杂的DOM操作,答案是"使用jQuery".
对于每个抱怨将"lodash"添加为"又一个"依赖关系的人:对于这类事情来说,它是一个相当常见的(如果不是最常见的)库.玩得开心重新发明轮子.
我明白你的意思了,@不得,谢谢.顺便说一句,如果一个人不喜欢包含整个lodash库,那么可以编译子组件或`npm install lodash.has`,它只显示一个带有`has`函数的npm模块,当缩小时可以编译为175个字节.查看`lodash.has/index.js`以了解一个非常受欢迎和受信任的库是如何工作的也很有见地.
即使你想重新发明轮子,检查现有的轮子也不是一个坏主意.
和`lodash`的版本一起使用:`.has(undefined,'someKey')=> false`而``underscore`返回`undefined`
我不相信使用库是一个可以接受的答案,因为这个问题要求"在JavaScript中"而不是"使用JavaScript库".
为了爱上帝,使用Lodash或其他任何可用的库,直到JS找出它漂亮,小巧的小脑袋.至少如果你走这条路线,那么为了浏览器的兼容性,你可以减少数量惊人的箍跳.问题解决了.继续.
此外,OP可能甚至不知道它.所以说'在JavaScript中'或'与JQuery'并不意味着他们不会对他们可能不知道存在的新库开放,只是试图使用基本的Javascript或Jquery,因为他们认为这是他们可以随意使用的所有这个.但是,选择使用'hasOwnProperty'的答案是最简单的方法.

3> Konrad Rudol..:

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


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

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

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

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

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

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


如果着名的"别人"重新定义了undefined是什么,我认为最好的做法是重写那些代码.
好奇,因为`void 0`被定义为返回规范的`undefined`,可以做`x.attribute!== void 0`?
拥有一个可靠的undefined var的最好方法是在一个闭包中工作,并且有一个不匹配的函数签名:`(function(undefined){// undefined实际上是未定义的}}();`

4> Whisher..:

关于什么?

var x = {'key': 1};

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


需要注意的是,它适用于狭义上的"对象",因此声明为{}或使用构造函数创建,它不接受数组或基元.并不是说OP需要它,但是其他一些答案提出了更广泛的技术(使用数组,字符串等)
x`**_ do _**中的''key'适用于数组.证明:http://stackoverflow.com/questions/33592385/if-0-in-array-is-this-even-legal

5> enobrev..:
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';
};


`Object.prototype`已经有一个内置的,正确的`hasOwnProperty`.用不正确的实现覆盖它(1.属性可以具有值'undefined`,2.这将为继承的属性提供误报)只是一个可怕的坏主意.可以并且应该删除不正确的答案.我不知道你是否可以在08年9月[当你看到Resig的回答时]那样做(http://stackoverflow.com/questions/135448/how-do-i-check-if-an-object-has -a-property-in-javascript/135475#comment35250_136411),所以评论建议现在就做.

6> goonerify..:

您可以使用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,在这种情况下,using typeof x.key仍将返回true(即使键仍然是在对象中).

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

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

这应该有效,除非undefined在x对象上专门设置了键



7> AnthonyWJone..:

让我们在这里切入一些困惑.首先,让我们假设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

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

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



8> Gerard ONeil..:

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

if ('prop' in obj) { }

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

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

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



9> Armin Ronach..:

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

但是那可以测试自己的属性.如果你想检查它是否有一个也可能被加入的属性你可以使用typeof x.foo != 'undefined'.



10> davidhadas..:

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

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

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

细节

在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)... 根据用例的不同,速度要慢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])...因为我觉得它更具可读性.

玩得开心.



11> Wilt..:

您还可以使用ES6 Reflect对象:

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

有关MDN的文档Reflect.has可在此处找到.

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



12> 小智..:
if (typeof x.key != "undefined") {

}

因为

if (x.key)

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



13> sheats..:

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

if (x.hasOwnProperty('key'))

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

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

if (x.key !== undefined)


警告x.hasOwnProperty('key')可以为true,而x.key!== undefined不为真.
对于`var x = {key:false};```x.key`方法是不正确的.
如果(x.key)像x = {key:0}一样不正确,它将不会通过检查。

14> Abdullah Dan..:

请勿这样做,这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));


我同意这种方法,它应该是公认的答案,因为这是保持性能的最安全方法!https://eslint.org/docs/rules/no-prototype-builtins说:“例如,网络服务器解析客户端的JSON输入并直接在生成的对象上调用hasOwnProperty是不安全的,因为恶意客户端可能发送诸如{“ hasOwnProperty”:1}之类的JSON值,并导致服务器崩溃。

15> 小智..:

hasOwnProperty"可用于确定对象是否具有指定属性作为该对象的直接属性; 与in运算符不同,此方法不会检查对象的原型链."

所以最有可能的是,对于你的问题看来,你不想使用hasOwnProperty,它确定属性是否存在直接附加到对象本身,.

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

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

我希望这有帮助.



16> Jamie Hutber..:

另一种相对简单的方法是使用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开始可以安全使用


然后您将执行Object.keys(info).indexOf('someotherthing')!== -1`
推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有