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

如何枚举JavaScript对象的属性?

如何解决《如何枚举JavaScript对象的属性?》经验,为你挑选了12个好方法。

如何枚举JavaScript对象的属性?

我实际上想要列出所有已定义的变量及其值,但我已经了解到定义变量实际上会创建窗口对象的属性.



1> Jason Buntin..:

很简单:

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}

现在,您不会以这种方式获取私有变量,因为它们不可用.


编辑:@bitwiseplatypus是正确的,除非你使用该hasOwnProperty()方法,你将获得继承的属性 - 但是,我不知道为什么熟悉面向对象编程的人会期望更少!通常情况下,提起这件事的人一直受到道格拉斯·克罗克福德(Douglas Crockford)关于此事的警告,这仍然让我感到困惑.同样,继承是OO语言的正常部分,因此它是JavaScript的一部分,尽管它是典型的.

现在,这么说,hasOwnProperty() 用于过滤是有用的,但我们并不需要发出警告声,好像有什么东西在得到继承属性危险.

编辑2:@bitwiseplatypus提出了如果有人在您最初​​编写对象(通过其原型)之后的某个时间点向对象添加属性/方法时会发生的情况 - 尽管这可能会导致意外行为,我个人并不认为这完全是我的问题.只是一个意见问题.此外,如果我以这样的方式设计东西,即在构造我的对象期间使用原型,然后让代码迭代对象的属性并且我想要所有继承的属性,该怎么办?我不会用hasOwnProperty().然后,让我们说,有人稍后会添加新属性.如果那时事情表现不好,这是我的错吗?我不这么认为.我认为这就是为什么jQuery作为一个例子,已经指定了扩展其工作方式的方法(通过jQuery.extendjQuery.fn.extend).


我认为*大多数人都很惊讶`for(x in {})`枚举任何东西,因为它看起来像一个简单的字典键迭代.这是非常意外的,绝对值得特别警告.
我认为@bitwiseplatypus只是说"小心".我的观点是,只有在提到hasOwnProperty()和其他不太明显的原型继承边缘情况时,才会教授JavaScript for/in.
我想知道人们实际遇到过多少次这样的错误.我做了一次,发现它真的很简单.教JS` for in`循环时的警告是好的,因此如果需要,可以过滤继承的属性.乱丢我的`for循环`盲目`hasOwnProperty`检查以迎合那些对JS没有基本了解的人**不是**保证.

2> Ryan Grove..:

使用for..in循环枚举对象的属性,但要小心.枚举将返回属性,不仅返回被枚举对象的属性,还返回任何父对象的原型.

var myObject = {foo: 'bar'};

for (var name in myObject) {
  alert(name);
}

// results in a single alert of 'foo'

Object.prototype.baz = 'quux';

for (var name in myObject) {
  alert(name);
}

// results in two alerts, one for 'foo' and one for 'baz'

要避免在枚举中包含继承的属性,请检查hasOwnProperty():

for (var name in myObject) {
  if (myObject.hasOwnProperty(name)) {
    alert(name);
  }
}

编辑:我不同意JasonBunting的声明,即我们不需要担心枚举继承的属性.还有就是在枚举了,你是不是希望继承属性,因为它可以改变你的代码的行为危险.

这个问题是否存在于其他语言中并不重要; 事实是它存在,并且JavaScript特别容易受到攻击,因为对对象原型的修改会影响子对象,即使在实例化之后进行修改也是如此.

这就是JavaScript提供的原因hasOwnProperty(),这就是为什么你应该使用它来确保第三方代码(或任何其他可能修改原型的代码)不会破坏你的原因.除了添加一些额外的代码字节外,使用没有任何缺点hasOwnProperty().


需要使用此模式,因为javascript将"Actor对象"与"哈希表"混淆.当对象是行为和特征*的描述时,通常的规则适用,你想知道对象的属性而不关心它们是如何到达那里的.另一方面,如果您将对象用作键值存储,那么您很可能只对实际存储在对象上的实际键感兴趣.其他属性是巧合的,并不代表对象的实际状态.其他语言用不同的类型解决了这种区别.
hasOwnProperty的奉献者通常是那些a)遭受侵略性公共库[例如:大约2003年的Prototype.js],或b)为异构系统构建基础的人(想想:web门户).其他人应该在迭代器模式中包装hasOwnProperty并出去喝啤酒.

3> Fabian Jakob..:

已经多次提出的标准方法是:

for (var name in myObject) {
  alert(name);
}

但是,Internet Explorer 6,7和8在JavaScript解释器中有一个错误,其效果是某些键未被枚举.如果您运行此代码:

var obj = { toString: 12};
for (var name in obj) {
  alert(name);
}

如果在IE以外的所有浏览器中都会提示"12".IE将简单地忽略此密钥.受影响的键值为:

isPrototypeOf

hasOwnProperty

toLocaleString

toString

valueOf

要在IE中真正安全,你必须使用类似的东西:

for (var key in myObject) {
  alert(key);
}

var shadowedKeys = [
  "isPrototypeOf",
  "hasOwnProperty",
  "toLocaleString",
  "toString",
  "valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i

好消息是EcmaScript 5定义了Object.keys(myObject)函数,它将对象的键作为数组返回,而某些浏览器(例如Safari 4)已经实现了它.



4> 小智..:

在现代浏览器(ECMAScript 5)中,您可以执行以下所有可枚举属性:

Object.keys(obj) (检查链接以获取旧版浏览器向后兼容性的片段)

或者获得非可枚举的属性:

Object.getOwnPropertyNames(OBJ)

检查ECMAScript 5兼容性表

附加信息: 什么是可枚举属性?


如果要处理某种类型的Error对象(例如TypeError),则需要使用Object.getOwnPropertyNames(obj),因为这些属性不可枚举。

5> 小智..:

我认为令我感到意外的一个例子是相关的:

var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
  document.writeln( propertyName + " : " + myObject[propertyName] );
}

但令我惊讶的是,输出是

name : Cody
status : Surprised
forEach : function (obj, callback) {
    for (prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
            callback(prop);
        }
    }
}

为什么?页面上的另一个脚本扩展了Object原型:

Object.prototype.forEach = function (obj, callback) {
  for ( prop in obj ) {
    if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
      callback( prop );
    }
  }
};



6> Andrew Hedge..:
for (prop in obj) {
    alert(prop + ' = ' + obj[prop]);
}



7> EmRa228..:

简单的JavaScript代码:

for(var propertyName in myObject) {
   // propertyName is what you want.
   // You can get the value like this: myObject[propertyName]
}

jQuery的:

jQuery.each(obj, function(key, value) {
   // key is what you want.
   // The value is in: value
});



8> davenpcj..:

我发现它... for (property in object) { // do stuff }将列出所有属性,因此列出窗口对象上的所有全局声明的变量.



9> Chtiwi Malek..:

以下是枚举对象属性的方法:

var params = { name: 'myname', age: 'myage' }

for (var key in params) {
  alert(key + "=" + params[key]);
}



10> dkl..:

如果您使用的是Underscore.js库,则可以使用功能键:

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]



11> Walle Cyril..:

您可以使用forof循环。

如果要使用数组:

Object.keys(object1)

参考 Object.keys()



12> Fabio Montef..:

Python的dict有'keys'方法,这非常有用.我认为在JavaScript中我们可以有这样的东西:

function keys(){
    var k = [];
    for(var p in this) {
        if(this.hasOwnProperty(p))
            k.push(p);
    }
    return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });

编辑:但@ carlos-ruana的答案非常有效.我测试了Object.keys(窗口),结果就是我的预期.

5年后编辑:扩展并不是一个好主意Object,因为它可能与其他可能想要keys在其对象上使用的库发生冲突,并且会导致项目出现不可预测的行为.@ carlos-ruana回答是获取对象键的正确方法.

推荐阅读
可爱的天使keven_464
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有