Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/479.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在循环中使用对象_Javascript_For Loop_Ecmascript 6_Iterable - Fatal编程技术网

Javascript 在循环中使用对象

Javascript 在循环中使用对象,javascript,for-loop,ecmascript-6,iterable,Javascript,For Loop,Ecmascript 6,Iterable,为什么不能在循环中使用对象?或者这是一个浏览器错误?此代码在Chrome 42中不起作用,表示undefined不是一个函数: test = { first: "one"} for(var item of test) { console.log(item) } 仅支持像数组这样的iterable对象,而不支持对象 要迭代对象的值,请使用: for (var key in test) { var item = test[key]; } 如果您将数据存储在键值存储中,则键值存储明确

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

test = { first: "one"}

for(var item of test) {
  console.log(item)
}
仅支持像数组这样的iterable对象,而不支持对象

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

for (var key in test) {
    var item = test[key];
}

如果您将数据存储在键值存储中,则键值存储明确为此目的而设计

如果必须使用对象,ES2017(ES8)允许您使用:

如果还不支持,请使用polyfill:

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

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

因为对象文字不具有该属性。具体来说,您只能使用循环在、、(不广泛支持)和上进行迭代

要处理对象文字迭代,有两个选项

为了……在 Object.keys+forEach
答案是否定的。不可能使用对象文字的..Of

我同意Overv的观点,For…Of只适用于iterables。 我有完全相同的问题,因为我使用对象在for..in中迭代键和值。但我刚刚意识到这就是ES6和ES6的用途

let test = new Map();
test.set('first', "one");
test.set('second', "two");

for(var item of test) {
  console.log(item); // "one" "two"
}
因此,它实现了不必使用..In(使用hasOwnProperty验证)和不必使用Object.keys()的目标


此外,键不限于字符串。您可以使用数字、对象或其他文字。

我使用以下代码使对象可编辑:

Object.prototype[Symbol.iterator] = function*() {
 for(let key of Object.keys(this)) {
  yield([ key, this[key] ])
} }
用法:

for(let [ key, value ] of {}) { }
或者:

for(let [ key, value ] of Object.entries({})) { }

您可以使用以下语法:

let myObject = {first: "one"};

for(let [key, value] of Object.entries(myObject)) {
    console.log(key, value); // "first", "one"
}
但是,目前支持较差,在IE或iOS Safari中不起作用。您可能需要一个polyfill。

使用它怎么样

function* entries(obj) {
    for (let key of Object.keys(obj)) {
        yield [key, obj[key]];
    }
}

for ([key, value] of entries({a: "1", b: "2"})) {
    console.log(key + " " + value);
}

对象文本没有内置的迭代器,这是使用
for…of
循环所必需的。但是,如果您不想麻烦地将自己的
[Symbol.iterator]
添加到对象中,只需使用
object.keys()
方法即可。此方法返回一个
数组
对象,该对象已经有一个内置迭代器,因此您可以将其与
for…of
循环一起使用,如下所示:

const myObject = {
    country: "Canada",
    province: "Quebec",
    city: "Montreal"
}

for (let i of Object.keys(myObject)) {
    console.log("Key:", i, "| Value:", myObject[i]);
}

//Key: country | Value: Canada
//Key: province | Value: Quebec
//Key: city | Value: Montreal

可以在任何给定对象上定义迭代器,这样您可以为每个对象放置不同的逻辑

var x = { a: 1, b: 2, c: 3 }
x[Symbol.iterator] = function* (){
    yield 1;
    yield 'foo';
    yield 'last'
}
然后直接迭代
x

for (let i in x){
    console.log(i);
}
//1
//foo
//last
可以对
对象.prototype
对象执行相同的操作,并为所有对象提供通用迭代器

Object.prototype[Symbol.iterator] = function*() {
    for(let key of Object.keys(this)) {
         yield key 
    } 
 }
然后像这样迭代对象

var t = {a :'foo', b : 'bar'}
for(let i of t){
    console.log(t[i]);
}
还是这样

var it = t[Symbol.iterator](), p;
while(p = it.next().value){
    console.log(t[p])
}

在ES6中,您可以使用发电机:

var obj = {1: 'a', 2: 'b'};

function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

let generator = entries(obj);

let step1 = generator.next();
let step2 = generator.next();
let step3 = generator.next();

console.log(JSON.stringify(step1)); // {"value":["1","a"],"done":false}
console.log(JSON.stringify(step2)); // {"value":["2","b"],"done":false}
console.log(JSON.stringify(step3)); // {"done":true}
在输出中,您将获得一个带有
“value”
“done”
键的对象<代码>“值”包含您希望它拥有的所有内容,
“完成”
是bool中迭代的当前状态

ECMAScript 2015/ES6中循环的迭代器、Iterable和for

但如果我们这样做了

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

for(element of tempObj) {
   console.log(element);
}
// error
我们得到错误是因为,for..of循环只对Iterables起作用,也就是说,对象有一个遵循迭代器协议的@@iterator,这意味着它必须有一个具有next方法的对象。下一个方法不接受任何参数,它应该返回一个具有这两个属性的对象

done:表示序列已结束,如果为true,则表示可能有更多值 :这是序列中的当前项

因此,要使对象Iterable,即使其与for..of一起工作,我们可以:

1.通过符号将对象指定给其神秘的@@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
let tempObj = {a:1, b:2, c:3};
for (let key of Object.keys(tempObj)) {
    console.log(key);
}

// a
// b
// c
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
3.使用Object.keys
,如下所示:

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
let tempObj = {a:1, b:2, c:3};
for (let key of Object.keys(tempObj)) {
    console.log(key);
}

// a
// b
// c

希望这有帮助

我只是做了以下几点来轻松地安慰我的东西

for (let key in obj) {
  if(obj.hasOwnProperty(key){
    console.log(`${key}: ${obj[key]}`);
  }
}
使用获取一组密钥怎么样?然后呢


使用数组销毁,您可以使用
forEach

const obj = { a: 5, b: 7, c: 9 };

Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

测试是数组还是对象?@KickButtowski,你看不见吗?它肯定是一个object.for(let key of object.keys(test)){…}@DanielHerr有一个
.iterable
成员函数,当您试图在一个对象(没有)上使用它时,会出现错误。我是说,为什么物体没有这个?以本机方式添加它会有什么问题?@DanielHerr我没有答案,您必须询问语言的设计人员。@DanielHerr如果对象“基类”是可移植的,那么任何函数/日期/等“子类”以及其他复杂情况都会是可移植的。请参阅,以获得对您的问题的更全面/准确的讨论。在解决方案中,使用此for..时,您在技术上是否仍需要检查if(test.hasOwnProperty(key)){…}?或者这是不需要的?对象原型不能扩展以支持这一点吗?@SonicSoul:技术上是的,但一般不建议将对象原型扩展为(几乎)一切都继承自它。
Object。条目可以通过多边形填充而不接触原型。为什么使用贴图而不是对象?使用这些复杂的示例比简单的
for in
有什么优势吗?不知道为什么这是公认的解决方案。修改原型,除非它是一个polyfill,这总是一个糟糕的想法。@user1703761它是公认的解决方案,因为它可以工作。请解释一下,如果情况如此糟糕,会导致什么问题。有各种各样的问题,主要是前向兼容性问题。一个例子是Array.prototype.includes,它以前是名称包含的,但是Moo工具扩展了原型,并且实现不兼容,请参见查找原型库desaster;)我相信这不会有向前兼容性问题,因为
for (let key in obj) {
  if(obj.hasOwnProperty(key){
    console.log(`${key}: ${obj[key]}`);
  }
}
obj = { a: 1, b:2}
Object.keys(obj).forEach( key => console.log(`${key} => ${obj[key]}`))
const obj = { a: 5, b: 7, c: 9 };

Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});