我有一个JavaScript对象,如下所示:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
我如何循环遍历p的所有元素(p1、p2、p3…)并获取它们的键和值?
我有一个JavaScript对象,如下所示:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
我如何循环遍历p的所有元素(p1、p2、p3…)并获取它们的键和值?
当前回答
考虑到ES6,我想添加自己的一勺糖,并提供另一种方法来迭代对象的财产。
由于纯JS对象不能立即迭代,因此我们无法使用。。用于迭代其内容的循环。但没有人能阻止我们使其可迭代。
让我们有书的对象。
let book = {
title: "Amazing book",
author: "Me",
pages: 3
}
book[Symbol.iterator] = function(){
let properties = Object.keys(this); // returns an array with property names
let counter = 0;
let isDone = false;
let next = () => {
if(counter >= properties.length){
isDone = true;
}
return { done: isDone, value: this[properties[counter++]] }
}
return { next };
}
既然我们做到了,我们可以这样使用它:
for(let pValue of book){
console.log(pValue);
}
------------------------
Amazing book
Me
3
或者如果你知道ES6发电机的功率,那么你当然可以让上面的代码更短。
book[Symbol.iterator] = function *(){
let properties = Object.keys(this);
for (let p of properties){
yield this[p];
}
}
当然,通过在原型级别上使Object可迭代,您可以对所有对象应用这样的行为。
Object.prototype[Symbol.iterator] = function() {...}
此外,符合可迭代协议的对象可以与新的ES2015特性扩展运算符一起使用,因此我们可以将对象属性值作为数组读取。
let pValues = [...book];
console.log(pValues);
-------------------------
["Amazing book", "Me", 3]
或者可以使用析构函数赋值:
let [title, , pages] = book; // notice that we can just skip unnecessary values
console.log(title);
console.log(pages);
------------------
Amazing book
3
您可以使用我上面提供的所有代码查看JSFiddle。
其他回答
您可以像这样迭代:
for (var key in p) {
alert(p[key]);
}
注意,键不会接受属性的值,它只是一个索引值。
我会这样做,而不是在每个for…中检查obj.hasOwnerProperty。。。在循环中。
var obj = {a : 1};
for(var key in obj){
//obj.hasOwnProperty(key) is not needed.
console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
throw new Error("Please don't extend the native object");
}
Object.entries()函数:
变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};for(Object.entries(p)中的var i){var key=对象条目(p)[i][0];var value=对象条目(p)[i][1];console.log('key['+i+']='+key+'+'value['+i+']='+value);}
前言:
对象财产可以是自己的(属性在对象本身上),也可以是继承的(不在对象本身或其原型上)。对象财产可以是可枚举的或非可枚举的。在许多属性枚举/数组中,不包含非数财产。属性名称可以是字符串或符号。许多属性枚举/数组都没有包含名称为Symbol的财产。
2018年,您可以选择循环访问对象的财产(以下是一些示例):
for-in[MDN,spec]-一种循环结构,循环遍历对象的可枚举财产的名称,包括名称为字符串的继承属性keys[MDN,spec]-一个函数,提供对象自己的可枚举财产的名称数组,这些属性的名称是字符串。Object.values[MDN,spec]-提供对象自身可枚举财产值数组的函数。Object.entries[MDN,spec]-提供对象自身可枚举财产的名称和值数组的函数(数组中的每个条目都是[name,value]数组)。Object.getOwnPropertyNames[MDN,spec]-一个函数,提供对象自己的财产(即使是不可枚举的属性)的名称数组,这些属性的名称是字符串。Object.getOwnPropertySymbols[MDN,spec]-一个函数,提供对象自己的财产(即使是不可枚举的属性)的名称数组,其名称为Symbols。Reflect.ownKeys[MDN,spec]-一个函数,提供对象自己的财产(即使是非枚举属性)的名称数组,无论这些名称是字符串还是符号。如果需要对象的所有财产,包括非枚举继承的属性,则需要使用循环和object.getPrototypeOf[MDN,spec],并在原型链中的每个对象上使用object.getOwnPropertyNames、object.getOwnPropertySymbols或Reflect.ownKeys(此答案底部的示例)。
对于除in之外的所有元素,您将在数组上使用某种循环构造(for、for、forEach等)。
示例:
中的:
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(o中的常量名称){常量值=o[名称];console.log(`${name}=${value}`);}
Object.keys(带有for of循环,但可以使用任何循环构造):
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(Object.keys(o)的常量名称){常量值=o[名称];console.log(`${name}=${value}`);}
对象值:
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(Object.values(o)的常量值){console.log(`${value}`);}
对象条目:
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(Object.entries(o)的常量[名称,值]){console.log(`${name}=${value}`);}
Object.getOwnPropertyName:
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(Object.getOwnPropertyNames(o)的常量名称){常量值=o[名称];console.log(`${name}=${value}`);}
Object.getOwnPropertySymbols:
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(Object.getOwnPropertySymbol(o)的常量名称){常量值=o[名称];console.log(`${String(name)}=${value}`);}
反射所有键:
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(Reflect.ownKeys(o)的常量名称){常量值=o[名称];console.log(`${String(name)}=${value}`);}
所有财产,包括继承的非枚举属性:
//要从中继承的原型对象,具有名为property的字符串常量p={answer:42};//我们将看到的对象继承自`p`const o=对象创建(p);//名为property的字符串o.question=“生命、宇宙和一切”;//名为属性的符号o[Symbol(“author”)]=“Douglas Adams”;for(让深度=0,当前=o;当前;++深度,当前=Object.getPrototypeOf(当前)){for(Reflect.ownKeys(当前)的常量名称){常量值=o[名称];console.log(`[${depth}]${String(name)}=${字符串(value)}`);}}.作为控制台包装{最大高度:100%!重要的}
在最新的ES脚本中,您可以执行以下操作:
让p={foo:“bar”};for(let[key,value]of Object.entries(p)){console.log(键,值);}