变量obj={name:“西蒙”,年龄:“20”,服装:{style:“简单”,嬉皮士:假}}for(obj中的var propt){console.log(propt+':'+obj[propt]);}
变量propt如何表示对象的财产?它不是内置方法或属性。为什么它会产生对象中的每个属性?
变量obj={name:“西蒙”,年龄:“20”,服装:{style:“简单”,嬉皮士:假}}for(obj中的var propt){console.log(propt+':'+obj[propt]);}
变量propt如何表示对象的财产?它不是内置方法或属性。为什么它会产生对象中的每个属性?
for循环遍历对象的所有财产。propt在for循环的第一行中定义。它是一个字符串,是obj对象的属性的名称。在循环的第一次迭代中,propt将是“name”。
迭代财产需要额外的hasOwnProperty检查:
for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
// do stuff
}
}
这是必要的,因为对象的原型包含对象的附加财产,这些属性在技术上是对象的一部分。这些附加的财产继承自基本对象类,但仍然是obj的财产。
hasOwnProperty只是检查这是否是该类特有的属性,而不是从基类继承的属性。
也可以通过对象本身调用hasOwnProperty:
if (obj.hasOwnProperty(prop)) {
// do stuff
}
但如果对象具有同名的不相关字段,则此操作将失败:
var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo'); // TypeError: hasOwnProperty is not a function
这就是为什么通过Object.prototype调用它更安全的原因:
var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo'); // true
从JavaScript 1.8.5开始,您可以使用Object.keys(obj)获取在对象本身上定义的财产数组(obj.hasOwnProperty(key)返回true的属性)。
Object.keys(obj).forEach(function(key,index) {
// key: the name of the object key
// index: the ordinal position of the key within the object
});
这比使用for in循环更好(更可读)。
这些浏览器支持:
Firefox(壁虎):4(2.0)铬:5Internet Explorer:9
有关更多信息,请参阅Mozilla Developer Network Object.keys()的参考。
为何在循环中,它创建了一个新变量(varsomeVariable),然后将给定对象的每个属性逐一存储在这个新变量(someVariable)中。因此,如果使用块{},则可以进行迭代。考虑以下示例。
var obj = {
name:'raman',
hobby:'coding',
planet:'earth'
};
for(var someVariable in obj) {
//do nothing..
}
console.log(someVariable); // outputs planet
用于。。。in循环表示对象中的每个属性,因为它就像for循环。您在for中定义了propt。。。在循环中执行以下操作:
for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}
A代表。。。在循环中迭代对象的可枚举财产。无论您定义哪个变量,或将其放入for。。。在循环中,每次转到它迭代的下一个属性时都会发生更改。for中的变量。。。in循环遍历键,但它的值是键的值。例如:
for(var propt in obj) {
console.log(propt);//logs name
console.log(obj[propt]);//logs "Simon"
}
您可以看到变量与变量值的区别。相比之下,a for。。。of循环则相反。
我希望这有帮助。
我想补充上面的答案,因为您可能与Javascript有不同的意图。JSON对象和Javascript对象是不同的东西,您可能想使用上面提出的解决方案迭代JSON对象的财产,然后感到惊讶。
假设您有一个JSON对象,如:
var example = {
"prop1": "value1",
"prop2": [ "value2_0", "value2_1"],
"prop3": {
"prop3_1": "value3_1"
}
}
迭代其“财产”的错误方式:
function recursivelyIterateProperties(jsonObject) {
for (var prop in Object.keys(example)) {
console.log(prop);
recursivelyIterateProperties(jsonObject[prop]);
}
}
迭代prop1、prop2和prop3_1的财产时,您可能会惊讶地看到控制台记录0、1等。这些对象是序列,序列的索引是Javascript中该对象的财产。
递归迭代JSON对象财产的更好方法是首先检查该对象是否为序列:
function recursivelyIterateProperties(jsonObject) {
for (var prop in Object.keys(example)) {
console.log(prop);
if (!(typeof(jsonObject[prop]) === 'string')
&& !(jsonObject[prop] instanceof Array)) {
recursivelyIterateProperties(jsonObject[prop]);
}
}
}
还添加了递归方式:
function iterate(obj) {
// watch for objects we've already iterated so we won't end in endless cycle
// for cases like var foo = {}; foo.bar = foo; iterate(foo);
var walked = [];
var stack = [{obj: obj, stack: ''}];
while(stack.length > 0)
{
var item = stack.pop();
var obj = item.obj;
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] == "object") {
// check if we haven't iterated through the reference yet
var alreadyFound = false;
for(var i = 0; i < walked.length; i++)
{
if (walked[i] === obj[property])
{
alreadyFound = true;
break;
}
}
// new object reference
if (!alreadyFound)
{
walked.push(obj[property]);
stack.push({obj: obj[property], stack: item.stack + '.' + property});
}
}
else
{
console.log(item.stack + '.' + property + "=" + obj[property]);
}
}
}
}
}
用法:
iterate({ foo: "foo", bar: { foo: "foo"} });
在这里,我迭代每个节点并创建有意义的节点名称。如果您注意到,instanceOfArray和instanceOfObject几乎做了相同的事情(在我的应用程序中,我给出了不同的逻辑)
function iterate(obj,parent_node) {
parent_node = parent_node || '';
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var node = parent_node + "/" + property;
if(obj[property] instanceof Array) {
//console.log('array: ' + node + ":" + obj[property]);
iterate(obj[property],node)
} else if(obj[property] instanceof Object){
//console.log('Object: ' + node + ":" + obj[property]);
iterate(obj[property],node)
}
else {
console.log(node + ":" + obj[property]);
}
}
}
}
注:我受到了翁德雷·斯文达尔(Ondrej Svejdar)的回答的启发。但此解决方案具有更好的性能和更少的模糊性
jquery允许您立即执行以下操作:
$.each( obj, function( key, value ) {
alert( key + ": " + value );
});
您基本上希望循环遍历对象中的每个属性。
JSFiddle公司
var Dictionary = {
If: {
you: {
can: '',
make: ''
},
sense: ''
},
of: {
the: {
sentence: {
it: '',
worked: ''
}
}
}
};
function Iterate(obj) {
for (prop in obj) {
if (obj.hasOwnProperty(prop) && isNaN(prop)) {
console.log(prop + ': ' + obj[prop]);
Iterate(obj[prop]);
}
}
}
Iterate(Dictionary);
现在,只需添加Symbol.iterator方法,就可以将标准JS对象转换为可迭代对象。然后可以使用for循环并直接访问其值,甚至可以在对象上使用扩展运算符。凉的让我们看看如何做到:
var o={a:1,b:2,c:3},a=[];o[Symbol.iiterator]=函数*(){var ok=对象.keys(this);i=0;而(i<ok长度)产生这个[ok[i++]];};for(o的var值)console.log(value);//或者你甚至可以这样做a=[…o];控制台日志(a);
在ES的最新实现中,您可以使用Object.entries:
for (const [key, value] of Object.entries(obj)) { }
or
Object.entries(obj).forEach(([key, value]) => ...)
如果您只想迭代这些值,请使用Object.values:
for (const value of Object.values(obj)) { }
or
Object.values(obj).forEach(value => ...)
你可以使用Lodash。文件
var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
...
});
女孩和男孩们,我们在2019年,我们没有那么多时间打字。。。所以,让我们来做这个酷炫的新花式ECMAScript 2016:
Object.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`));
let obj = {"a": 3, "b": 2, "6": "a"}
Object.keys(obj).forEach((item) => {console.log("item", obj[item])})
// a
// 3
// 2
为了进一步完善接受的答案,值得注意的是,如果使用var object=object.create(null)实例化对象,那么object.hasOwnProperty(property)将触发TypeError。所以为了安全起见,您需要从原型中调用它,如下所示:
for (var property in object) {
if (Object.prototype.hasOwnProperty.call(object, property)) {
// do stuff
}
}
如果您的环境支持ES2017,那么我将推荐Object.entries:
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`);
});
如Mozillas Object.entries()文档所示:
Object.entries()方法返回给定对象自身的数组可枚举属性[key,value]对,顺序与由…提供。。。in循环(区别在于for in循环还列举了原型链中的财产)。
基本上,使用Object.entries,我们可以放弃旧的for。。。循环中:
// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
// do stuff
}
上面的答案有点烦人,因为在你确定它是一个对象之后,它们没有解释你在for循环中做什么:你没有直接访问它!实际上,您只收到了需要应用于OBJ的密钥:
var obj = {
a: "foo",
b: "bar",
c: "foobar"
};
// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
// We check if this key exists in the obj
if (obj.hasOwnProperty(someKey))
{
// someKey is only the KEY (string)! Use it to get the obj:
var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"
// NOW you can treat it like an obj
var shouldBeBar = myActualPropFromObj.b;
}
}
这是所有ECMA5安全的。甚至可以在Rhino等蹩脚的JS版本中使用;)
Dominik的回答很完美,我更喜欢这样做,因为读起来更干净:
for (var property in obj) {
if (!obj.hasOwnProperty(property)) continue;
// Do stuff...
}
添加ES2015对Reflect.ownKeys(obj)的使用,并通过迭代器迭代财产。
例如:
let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };
可以通过
// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));
如果您想直接迭代对象的键的值,可以定义迭代器,就像JavaScipts的字符串、数组、类型化数组、Map和Set的默认迭代器一样。
JS将尝试通过默认迭代器属性进行迭代,该属性必须定义为Symbol.iterator。
如果希望能够遍历所有对象,可以将其添加为Object的原型:
Object.prototype[Symbol.iterator] = function*() {
for(p of Reflect.ownKeys(this)){ yield this[p]; }
}
这将使您能够使用for。。。例如:
for(val of obj) { console.log('Value is:' + val ) }
注意:截至撰写此答案(2018年6月),除IE外,所有其他浏览器都支持生成器和。。。通过Symbol.iterator迭代
虽然最高评级的答案是正确的,但这里有一个备用用例,即如果您正在迭代一个对象,并希望最终创建一个数组。使用.map而不是forEach
const newObj = Object.keys(obj).map(el => {
//ell will hold keys
// Getting the value of the keys should be as simple as obj[el]
})
if (typeof obj === 'object' && obj !== null) {
Object.keys(obj).forEach(key => {
console.log("\n" + key + ": " + obj[key]);
});
}
// *** Explanation line by line ***
// Explaining the bellow line
// It checks if obj is neither null nor undefined, which means it's safe to get its keys.
// Otherwise it will give you a "TypeError: Cannot convert undefined or null to object" if obj is null or undefined.
// NOTE 1: You can use Object.hasOwnProperty() instead of Object.keys(obj).length
// NOTE 2: No need to check if obj is an array because it will work just fine.
// NOTE 3: No need to check if obj is a string because it will not pass the 'if typeof obj is Object' statement.
// NOTE 4: No need to check if Obj is undefined because it will not pass the 'if type obj is Object' statement either.
if (typeof obj === 'object' && obj !== null) {
// Explaining the bellow line
// Just like in the previous line, this returns an array with
// all keys in obj (because if code execution got here, it means
// obj has keys.)
// Then just invoke built-in javascript forEach() to loop
// over each key in returned array and calls a call back function
// on each array element (key), using ES6 arrow function (=>)
// Or you can just use a normal function ((key) { blah blah }).
Object.keys(obj).forEach(key => {
// The bellow line prints out all keys with their
// respective value in obj.
// key comes from the returned array in Object.keys(obj)
// obj[key] returns the value of key in obj
console.log("\n" + key + ": " + obj[key]);
});
}
检查类型
您可以检查propt如何表示对象属性
typeof propt
发现它只是一个字符串(属性名称)。由于for in js“内置”循环的工作方式,它会生成对象中的每个属性。
变量obj={name:“西蒙”,年龄:“20”,服装:{style:“简单”,嬉皮士:假}}for(obj中的var propt){console.log(propt类型,propt+:“+obj[propt]);}
您可以使用for…访问对象的嵌套财产。。。in和forEach循环。
对于在:
for (const key in info) {
console.log(info[key]);
}
对于每个:
Object.keys(info).forEach(function(prop) {
console.log(info[prop]);
// cities: Array[3], continent: "North America", images: Array[3], name: "Canada"
// "prop" is the property name
// "data[prop]" is the property value
});
如果您只想迭代映射属性值,则lodash具有_.mapValues
常量对象={a: 2,b: 3个}常量res=_.map值(obj,v=>v*2)console.log(res)<script src=“https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js“></script>
实现这一点的简单明了的方法,即不迭代原型的现代JS,如下所示:
Object.prototype.iterateProperties = ((callback) => {
Object.keys(obj).filter(key => obj.hasOwnProperty(key)).forEach((key) => {
callback(key, obj[key]);
});
});
解释
这段代码在所有对象的原型中创建了一个可以在每个object实例中访问的函数。该函数迭代对象的所有自己的财产,并运行回调函数,该函数为对象中的每个属性获取(键、值)。
使用示例
obj.iterateProperties((key, value) => console.log(key + ': ' + value));