在for循环中使用对象

Dan*_*err 73 javascript for-loop iterable ecmascript-6

为什么不能在for循环中使用对象?或者这是一个浏览器错误?此代码在Chrome 42中不起作用,称undefined不是函数:

test = { first: "one"}

for(var item of test) {
  console.log(item)
}
Run Code Online (Sandbox Code Playgroud)

Ove*_*erv 66

for..of循环只支持像数组,而不是对象可迭代的对象.

要迭代对象的值,请使用:

for (var key in test) {
    var item = test[key];
}
Run Code Online (Sandbox Code Playgroud)

  • @DanielHerr如果Object"基类"是可迭代的,那么任何Function/Date/etc"子类"都会被复杂化.请参阅https://esdiscuss.org/topic/es6-iteration-over-object-values#content-5,以便更全面/准确地讨论您的问题. (6认同)
  • 有了这个for..in解决方案,你在技术上还是不得不检查`if(test.hasOwnProperty(key)){...}`吗?还是不需要? (5认同)
  • 我的意思是,为什么对象没有那个?本地添加它会有什么问题? (4认同)
  • @DanielHerr有一个`.iterable`成员函数,当你试图在一个对象(没有它)上使用它时,就会出现错误.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols (3认同)
  • @DanielHerr我没有答案,你必须问设计语言的人. (3认同)
  • @DanielHerr 可迭代(例如数组)和不可迭代(本机对象)集合之间的区别在于可迭代集合对其元素的迭代顺序有明确的定义。对象只是查找,并且规范规定您永远不应该依赖键或值的顺序(例如,当使用 for-in 循环时),因此它们不被认为是“可迭代的”。 (2认同)

mpe*_*pen 34

您可以使用以下语法:

let myObject = {first: "one"};

for(let [key, value] of Object.entries(myObject)) {
    console.log(key, value); // "first", "one"
}
Run Code Online (Sandbox Code Playgroud)

然而, Object.entries 现在支持不佳在IE或iOS Safari中不起作用.你可能需要一个polyfill.


Qan*_*avy 33

如果要将数据存储在键值存储中,请使用Map为此目的明确设计的数据.

如果你必须使用一个对象,ES2017(ES8)允许你使用Object.values:

const foo = { a: 'foo', z: 'bar', m: 'baz' };
for (let value of Object.values(foo)) {
    console.log(value);
}
Run Code Online (Sandbox Code Playgroud)

如果尚未支持,请使用polyfill:替代版本Object.values()

最后,如果您支持不支持此语法的旧环境,则必须使用forEachObject.keys:

var obj = { a: 'foo', z: 'bar', m: 'baz' };
Object.keys(obj).forEach(function (prop) {
    var value = obj[prop];
    console.log(value);
});
Run Code Online (Sandbox Code Playgroud)

  • 为什么使用地图而不是对象? (5认同)

Man*_*z90 18

ECMAScript 2015/ES6中的Iterator,Iterable和for..of循环

let tempArray = [1,2,3,4,5];

for(element of tempArray) {
  console.log(element);
}

// 1
// 2
// 3
// 4
// 5
Run Code Online (Sandbox Code Playgroud)

但如果我们这样做

let tempObj = {a:1, b:2, c:3};

for(element of tempObj) {
   console.log(element);
}
// error
Run Code Online (Sandbox Code Playgroud)

我们得到错误,因为for..of循环仅适用于Iterables,即具有符合Iterator协议@@迭代器的对象,这意味着它必须具有带有下一个方法的对象.下一个方法不带参数,它应该返回一个具有这两个属性的对象.

完成:信号,该序列已经真正结束的时候,假的手段可能有多个值 :这是序列中的当前项

因此,要创建一个Iterable对象,它可以使它与for..of一起使用,我们可以:

1. 通过Symbol.iterator属性将一个对象赋予一个Iterable,这是一个神秘的@@ iterator属性.这是如何:

let tempObj = {a:1, b:2, c:3};

tempObj[Symbol.iterator]= () => ({
next: function next () {
return {
    done: Object.keys(this).length === 0,
    value: Object.keys(this).shift()
     }
    }
  })

for(key in tempObj){
 console.log(key)
}
// a
// b
// c
Run Code Online (Sandbox Code Playgroud)

2.使用Object.entries,它返回一个Iterable:

let tempObj = {a:1, b:2, c:3};

for(let [key, value] of Object.entries(tempObj)) {
    console.log(key, value);
}
// a 1
// b 2
// c 3
Run Code Online (Sandbox Code Playgroud)

3.使用Object.keys,这是如何:

let tempObj = {a:1, b:2, c:3};
for (let key of Object.keys(tempObj)) {
    console.log(key);
}

// a
// b
// c
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!!!!!!


Dan*_*err 17

我用这段代码可以迭代对象:

Object.prototype[Symbol.iterator] = function*() {
 for(let key of Object.keys(this)) {
  yield([ key, this[key] ])
} }
Run Code Online (Sandbox Code Playgroud)

用法:

for(let [ key, value ] of {}) { }
Run Code Online (Sandbox Code Playgroud)

Alternativly:

for(let [ key, value ] of Object.entries({})) { }
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这是公认的解决方案.修改原型,除非它的polyfill总是一个糟糕的主意. (44认同)
  • 存在各种问题,主要是向前兼容问题.一个例子是Array.prototype.includes以前名称包含但是Moo Tools扩展了原型并且实现不兼容,请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=1075059还查看Prototype库desaster;) (8认同)
  • 嘿伙计们,修改原型是一个坏主意!让OP感到羞耻,实际上给出了问题的答案! (4认同)
  • 我相信这不会有前向兼容性问题,因为如果将迭代器添加到对象中,这将覆盖它,如果将迭代器添加到对象子类型,它将使用子类型迭代器. (3认同)
  • @ user1703761这是可接受的解决方案,因为它有效.请解释如果它如此可怕会导致什么问题. (2认同)

Lew*_*wis 12

因为object literal没有Symbol.iterator属性.具体而言,您只能遍历字符串,数组,地图,设置,参数,节点列表(没有得到广泛的支持)和 发电机的......的循环.

要处理Object Literal迭代,您有两个选择.

对于在...

for(let key in obj){
    console.log(obj[key]); 
}
Run Code Online (Sandbox Code Playgroud)

Object.keys + forEach

Object.keys(obj).forEach(function(key){
    console.log(obj[key]);
});
Run Code Online (Sandbox Code Playgroud)