在javascript中(in)和(of)有什么区别?

时间:2021-09-28 13:58:21

I know what is for... in loop(it iterate over key), but heard first time about for... of(it iterate over value). I am confused with for... of loop. I didn't get adject. This is the code below :

我知道什么是……在循环中(它遍历键),但是第一次听到关于…(它的遍历值)。我很困惑……的循环。我没有得到adject。这是下面的代码:

var arr = [3, 5, 7];
arr.foo = "hello";

for (var i in arr) {
   console.log(i); // logs "0", "1", "2", "foo"
}

for (var i of arr) {
   console.log(i); // logs "3", "5", "7"
    //it is does not log "3", "5", "7","hello"
}

What I got is, for... of iterates over property values. then why it doesn't log(return) "3", "5", "7","hello" instead of "3", "5", "7" ? but for... in loop iterate over each key ("0", "1", "2", "foo"). here for... in loop also iterate over foo key. but for... of not iterarte over value of foo property ie "hello".Why it is like that?

我得到的是…遍历属性值。那么为什么它不记录(返回)“3”、“5”、“7”、“你好”而不是“3”、“5”、“7”?但对于…在循环中迭代每个键(“0”、“1”、“2”、“foo”)。在这里……在循环中还对foo键进行迭代。但对于…不迭代foo属性的值即“hello”。为什么会这样?

Long story in short:

很长的故事简而言之:

here i console for... of loop. it should be log "3", "5", "7","hello" but here it logs "3", "5", "7". Why ?

我安慰……的循环。应该是log "3" 5" 7" hello"但这里是log "3" 5" 7"为什么?

Example Link

例子链接

6 个解决方案

#1


150  

for in loops over enumerable property names of an object.

在循环中遍历对象的可枚举属性名。

for of (new in ES6) does use an object-specific iterator and loops over the values generated by that.

for of (new in ES6)确实使用对象特定的迭代器,并对其产生的值进行循环。

In your example, the array iterator does yield all the values in the array (ignoring non-index properties).

在您的示例中,数组迭代器会产生数组中的所有值(忽略非索引属性)。

#2


111  

I find a complete answer at : https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html (Although it is for type script, this is same for javascript too)

我找到了一个完整的答案:https://www.typescriptlang.org/docs/handbook/iterator-generators.html(尽管它是用于类型脚本的,但对于javascript也是一样)

Both for..of and for..in statements iterate over lists; the values iterated on are different though, for..in returns a list of keys on the object being iterated, whereas for..of returns a list of values of the numeric properties of the object being iterated.

对. .和的. .在语句中迭代列表;但是迭代的值是不同的。返回被迭代对象上的键列表,而对于。返回一个被迭代对象的数值属性的值列表。

Here is an example that demonstrates this distinction:

这里有一个例子证明了这种区别:

let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}

Another distinction is that for..in operates on any object; it serves as a way to inspect properties on this object. for..of on the other hand, is mainly interested in values of iterable objects. Built-in objects like Map and Set implement Symbol.iterator property allowing access to stored values.

另一个区别是……对任何物体进行操作;它作为检查对象上属性的一种方法。为. .另一方面,它主要关注可迭代对象的值。内置对象,如地图和设置实现符号。迭代器属性,允许访问存储的值。

let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";

for (let pet in pets) {
   console.log(pet); // "species"
}

for (let pet of pets) {
    console.log(pet); // "Cat", "Dog", "Hamster"
}

#3


17  

For...in loop

The for...in loop improves upon the weaknesses of the for loop by eliminating the counting logic and exit condition.

为…在循环中,通过消除计数逻辑和退出条件,改进了for循环的缺点。

Example:

例子:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

But, you still have to deal with the issue of using an index to access the values of the array, and that stinks; it almost makes it more confusing than before.

但是,您仍然需要处理使用索引访问数组值的问题,这很糟糕;这几乎使它比以前更令人困惑。

Also, the for...in loop can get you into big trouble when you need to add an extra method to an array (or another object). Because for...in loops loop over all enumerable properties, this means if you add any additional properties to the array's prototype, then those properties will also appear in the loop.

此外,……当您需要向数组(或其他对象)添加额外的方法时,in循环可能会给您带来很大的麻烦。因为……在循环中,循环遍历所有可枚举属性,这意味着如果向数组的原型添加任何附加属性,那么这些属性也将出现在循环中。

Array.prototype.decimalfy = function() {
  for (let i = 0; i < this.length; i++) {
    this[i] = this[i].toFixed(2);
  }
};

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

Prints:

打印:

0

0

1

1

2

2

3

3

4

4

5

5

6

6

7

7

8

8

9

9

function() {  for (let i = 0; i < this.length; i++) {   this[i] = this[i].toFixed(2);  } }

函数(){for(设i = 0;我< this.length;{this[i] = this[i].toFixed(2);} }

This is why for...in loops are discouraged when looping over arrays.

这就是为什么……当循环遍历数组时,不鼓励循环。

NOTE: The forEach loop is another type of for loop in JavaScript. However, forEach() is actually an array method, so it can only be used exclusively with arrays. There is also no way to stop or break a forEach loop. If you need that type of behavior in your loop, you’ll have to use a basic for loop.

注意:forEach循环是JavaScript中的另一种for循环类型。然而,forEach()实际上是一个数组方法,所以它只能用于数组。也没有办法停止或中断forEach循环。如果在循环中需要这种类型的行为,则必须使用基本的for循环。

For...of loop

The for...of loop is used to loop over any type of data that is iterable.

为…循环用于循环遍历可迭代的任何类型的数据。

Example:

例子:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  console.log(digit);
}

Prints:

打印:

0

0

1

1

2

2

3

3

4

4

5

5

6

6

7

7

8

8

9

9

This makes the for...of loop the most concise version of all the for loops.

这使得……循环的最简洁版本的所有for循环。

But wait, there’s more! The for...of loop also has some additional benefits that fix the weaknesses of the for and for...in loops.

别急,还有更多!为…loop还有一些额外的好处,可以弥补for和for…在循环。

You can stop or break a for...of loop at anytime.

你可以为了…随时的循环。

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  if (digit % 2 === 0) {
    continue;
  }
  console.log(digit);
}

Prints:

打印:

1

1

3

3

5

5

7

7

9

9

And you don’t have to worry about adding new properties to objects. The for...of loop will only loop over the values in the object.

你不必担心向对象添加新属性。为…循环将只循环对象中的值。

#4


7  

The for-in statement iterates over the enumerable properties of an object, in arbitrary order.

forin语句以任意顺序遍历对象的可枚举属性。

The loop will iterate over all enumerable properties of the object itself and those the object inherits from its constructor's prototype

循环将遍历对象本身的所有可枚举属性,以及对象从构造函数的原型继承的属性

You can think of it as "for in" basically iterates and list out all the keys.

你可以把它想象成“for in”,它会迭代并列出所有的键。

var str = 'abc';
var arrForOf = [];
var arrForIn = [];

for(value of str){
  arrForOf.push(value);
}

for(value in str){
  arrForIn.push(value);
}

console.log(arrForOf); 
// ["a", "b", "c"]
console.log(arrForIn); 
// ["0", "1", "2", "formatUnicorn", "truncate", "splitOnLast", "contains"]

#5


1  

There are some already defined data types which allows us to iterate over them easily e.g Array, Map, String Objects

有一些已经定义的数据类型允许我们轻松地对它们进行迭代。g数组,映射,字符串对象

Normal for in iterates over the iterator and in response provides us with the keys that are in the order of insertion as shown in below example.

在迭代器上迭代和响应中,通常为我们提供按插入顺序排列的键,如下例所示。

  const numbers = [1,2,3,4,5];
   for(let number in number) {
     console.log(number);
   }

   // result: 0, 1, 2, 3, 4

Now if we try same with for of, then in response it provides us with the values not the keys. e.g

如果我们对它进行相同的尝试,那么作为响应,它为我们提供了值而不是键。如

  const numbers = [1,2,3,4,5];
   for(let numbers of numbers) {
    console.log(number);
  }

  // result: 1, 2, 3, 4, 5

So looking at both of the iterators we can easily differentiate the difference between both of them.

所以看两个迭代器我们可以很容易地区分它们的不同。

Note:- For of only works with the Symbol.iterator

注:- For仅适用于Symbol.iterator

So if we try to iterate over normal object, then it will give us an error e.g-

所以如果我们尝试遍历普通对象,它会给我们一个错误,例如-

const Room = {
   area: 1000,
   height: 7,
   floor: 2
 }

for(let prop in Room) {
 console.log(prop);
 } 

// Result area, height, floor

for(let prop of Room) {
  console.log(prop);
 } 

Room is not iterable

房间不是iterable

Now for iterating over we need to define an ES6 Symbol.iterator e.g

现在对于迭代,我们需要定义一个ES6符号。迭代器如

  const Room= {
    area: 1000, height: 7, floor: 2,
   [Symbol.iterator]: function* (){
    yield this.area;
    yield this.height;
    yield this.floors;
  }
}


for(let prop of Room) {
  console.log(prop);
 } 

//Result 1000, 7, 2

This is the difference between For in and For of. Hope that it might clear the difference.

这就是For in和For的区别。希望它能消除分歧。

#6


0  

The for...in statement iterates over the enumerable properties of an object, in an arbitrary order. Enumerable properties are those properties whose internal [[Enumerable]] flag is set to true, hence if there is any enumerable property in the prototype chain, the for...in loop will iterate on those as well.

为…在语句中,以任意顺序遍历对象的可枚举属性。可枚举属性是指其内部[[可枚举]]标志被设置为true的属性,因此,如果原型链中有任何可枚举属性,for…在循环中也会对它们进行迭代。

The for...of statement iterates over data that iterable object defines to be iterated over.

为…语句迭代要迭代的可迭代对象定义的数据。

Example

例子

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs 0, 1, 2,
  }
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}

Like earlier you can skip adding "hasOwnProperty" in for...of loops.

像之前一样,你可以跳过添加“hasOwnProperty”到……的循环。

#1


150  

for in loops over enumerable property names of an object.

在循环中遍历对象的可枚举属性名。

for of (new in ES6) does use an object-specific iterator and loops over the values generated by that.

for of (new in ES6)确实使用对象特定的迭代器,并对其产生的值进行循环。

In your example, the array iterator does yield all the values in the array (ignoring non-index properties).

在您的示例中,数组迭代器会产生数组中的所有值(忽略非索引属性)。

#2


111  

I find a complete answer at : https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html (Although it is for type script, this is same for javascript too)

我找到了一个完整的答案:https://www.typescriptlang.org/docs/handbook/iterator-generators.html(尽管它是用于类型脚本的,但对于javascript也是一样)

Both for..of and for..in statements iterate over lists; the values iterated on are different though, for..in returns a list of keys on the object being iterated, whereas for..of returns a list of values of the numeric properties of the object being iterated.

对. .和的. .在语句中迭代列表;但是迭代的值是不同的。返回被迭代对象上的键列表,而对于。返回一个被迭代对象的数值属性的值列表。

Here is an example that demonstrates this distinction:

这里有一个例子证明了这种区别:

let list = [4, 5, 6];

for (let i in list) {
   console.log(i); // "0", "1", "2",
}

for (let i of list) {
   console.log(i); // "4", "5", "6"
}

Another distinction is that for..in operates on any object; it serves as a way to inspect properties on this object. for..of on the other hand, is mainly interested in values of iterable objects. Built-in objects like Map and Set implement Symbol.iterator property allowing access to stored values.

另一个区别是……对任何物体进行操作;它作为检查对象上属性的一种方法。为. .另一方面,它主要关注可迭代对象的值。内置对象,如地图和设置实现符号。迭代器属性,允许访问存储的值。

let pets = new Set(["Cat", "Dog", "Hamster"]);
pets["species"] = "mammals";

for (let pet in pets) {
   console.log(pet); // "species"
}

for (let pet of pets) {
    console.log(pet); // "Cat", "Dog", "Hamster"
}

#3


17  

For...in loop

The for...in loop improves upon the weaknesses of the for loop by eliminating the counting logic and exit condition.

为…在循环中,通过消除计数逻辑和退出条件,改进了for循环的缺点。

Example:

例子:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

But, you still have to deal with the issue of using an index to access the values of the array, and that stinks; it almost makes it more confusing than before.

但是,您仍然需要处理使用索引访问数组值的问题,这很糟糕;这几乎使它比以前更令人困惑。

Also, the for...in loop can get you into big trouble when you need to add an extra method to an array (or another object). Because for...in loops loop over all enumerable properties, this means if you add any additional properties to the array's prototype, then those properties will also appear in the loop.

此外,……当您需要向数组(或其他对象)添加额外的方法时,in循环可能会给您带来很大的麻烦。因为……在循环中,循环遍历所有可枚举属性,这意味着如果向数组的原型添加任何附加属性,那么这些属性也将出现在循环中。

Array.prototype.decimalfy = function() {
  for (let i = 0; i < this.length; i++) {
    this[i] = this[i].toFixed(2);
  }
};

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const index in digits) {
  console.log(digits[index]);
}

Prints:

打印:

0

0

1

1

2

2

3

3

4

4

5

5

6

6

7

7

8

8

9

9

function() {  for (let i = 0; i < this.length; i++) {   this[i] = this[i].toFixed(2);  } }

函数(){for(设i = 0;我< this.length;{this[i] = this[i].toFixed(2);} }

This is why for...in loops are discouraged when looping over arrays.

这就是为什么……当循环遍历数组时,不鼓励循环。

NOTE: The forEach loop is another type of for loop in JavaScript. However, forEach() is actually an array method, so it can only be used exclusively with arrays. There is also no way to stop or break a forEach loop. If you need that type of behavior in your loop, you’ll have to use a basic for loop.

注意:forEach循环是JavaScript中的另一种for循环类型。然而,forEach()实际上是一个数组方法,所以它只能用于数组。也没有办法停止或中断forEach循环。如果在循环中需要这种类型的行为,则必须使用基本的for循环。

For...of loop

The for...of loop is used to loop over any type of data that is iterable.

为…循环用于循环遍历可迭代的任何类型的数据。

Example:

例子:

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  console.log(digit);
}

Prints:

打印:

0

0

1

1

2

2

3

3

4

4

5

5

6

6

7

7

8

8

9

9

This makes the for...of loop the most concise version of all the for loops.

这使得……循环的最简洁版本的所有for循环。

But wait, there’s more! The for...of loop also has some additional benefits that fix the weaknesses of the for and for...in loops.

别急,还有更多!为…loop还有一些额外的好处,可以弥补for和for…在循环。

You can stop or break a for...of loop at anytime.

你可以为了…随时的循环。

const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

for (const digit of digits) {
  if (digit % 2 === 0) {
    continue;
  }
  console.log(digit);
}

Prints:

打印:

1

1

3

3

5

5

7

7

9

9

And you don’t have to worry about adding new properties to objects. The for...of loop will only loop over the values in the object.

你不必担心向对象添加新属性。为…循环将只循环对象中的值。

#4


7  

The for-in statement iterates over the enumerable properties of an object, in arbitrary order.

forin语句以任意顺序遍历对象的可枚举属性。

The loop will iterate over all enumerable properties of the object itself and those the object inherits from its constructor's prototype

循环将遍历对象本身的所有可枚举属性,以及对象从构造函数的原型继承的属性

You can think of it as "for in" basically iterates and list out all the keys.

你可以把它想象成“for in”,它会迭代并列出所有的键。

var str = 'abc';
var arrForOf = [];
var arrForIn = [];

for(value of str){
  arrForOf.push(value);
}

for(value in str){
  arrForIn.push(value);
}

console.log(arrForOf); 
// ["a", "b", "c"]
console.log(arrForIn); 
// ["0", "1", "2", "formatUnicorn", "truncate", "splitOnLast", "contains"]

#5


1  

There are some already defined data types which allows us to iterate over them easily e.g Array, Map, String Objects

有一些已经定义的数据类型允许我们轻松地对它们进行迭代。g数组,映射,字符串对象

Normal for in iterates over the iterator and in response provides us with the keys that are in the order of insertion as shown in below example.

在迭代器上迭代和响应中,通常为我们提供按插入顺序排列的键,如下例所示。

  const numbers = [1,2,3,4,5];
   for(let number in number) {
     console.log(number);
   }

   // result: 0, 1, 2, 3, 4

Now if we try same with for of, then in response it provides us with the values not the keys. e.g

如果我们对它进行相同的尝试,那么作为响应,它为我们提供了值而不是键。如

  const numbers = [1,2,3,4,5];
   for(let numbers of numbers) {
    console.log(number);
  }

  // result: 1, 2, 3, 4, 5

So looking at both of the iterators we can easily differentiate the difference between both of them.

所以看两个迭代器我们可以很容易地区分它们的不同。

Note:- For of only works with the Symbol.iterator

注:- For仅适用于Symbol.iterator

So if we try to iterate over normal object, then it will give us an error e.g-

所以如果我们尝试遍历普通对象,它会给我们一个错误,例如-

const Room = {
   area: 1000,
   height: 7,
   floor: 2
 }

for(let prop in Room) {
 console.log(prop);
 } 

// Result area, height, floor

for(let prop of Room) {
  console.log(prop);
 } 

Room is not iterable

房间不是iterable

Now for iterating over we need to define an ES6 Symbol.iterator e.g

现在对于迭代,我们需要定义一个ES6符号。迭代器如

  const Room= {
    area: 1000, height: 7, floor: 2,
   [Symbol.iterator]: function* (){
    yield this.area;
    yield this.height;
    yield this.floors;
  }
}


for(let prop of Room) {
  console.log(prop);
 } 

//Result 1000, 7, 2

This is the difference between For in and For of. Hope that it might clear the difference.

这就是For in和For的区别。希望它能消除分歧。

#6


0  

The for...in statement iterates over the enumerable properties of an object, in an arbitrary order. Enumerable properties are those properties whose internal [[Enumerable]] flag is set to true, hence if there is any enumerable property in the prototype chain, the for...in loop will iterate on those as well.

为…在语句中,以任意顺序遍历对象的可枚举属性。可枚举属性是指其内部[[可枚举]]标志被设置为true的属性,因此,如果原型链中有任何可枚举属性,for…在循环中也会对它们进行迭代。

The for...of statement iterates over data that iterable object defines to be iterated over.

为…语句迭代要迭代的可迭代对象定义的数据。

Example

例子

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {};

let iterable = [3, 5, 7];

for (let i in iterable) {
  console.log(i); // logs 0, 1, 2, "arrCustom", "objCustom"
}

for (let i in iterable) {
  if (iterable.hasOwnProperty(i)) {
    console.log(i); // logs 0, 1, 2,
  }
}

for (let i of iterable) {
  console.log(i); // logs 3, 5, 7
}

Like earlier you can skip adding "hasOwnProperty" in for...of loops.

像之前一样,你可以跳过添加“hasOwnProperty”到……的循环。