Muk*_*mar 337 javascript arrays object
我知道什么是for... in循环(它迭代密钥),但第一次听到for... of(它迭代值).我对for... of循环感到困惑.我没有得到.这是下面的代码:
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"
}
Run Code Online (Sandbox Code Playgroud)
我得到的是,for... of迭代属性值.那么为什么它不记录(返回)"3", "5", "7","hello"而不是"3", "5", "7"?但for... in循环迭代每个键("0","1","2","foo").这里for... in循环也迭代foo密钥.但是对于...不是对foo财产价值的迭代,即"hello"为什么它是这样的?
简而言之:
在这里我控制台for... of循环.它应该是日志,"3", "5", "7","hello"但在这里记录"3", "5", "7".为什么?
Ber*_*rgi 252
for in 循环遍历对象的可枚举属性名称.
for of(ES6中的新增功能)确实使用特定于对象的迭代器并循环其生成的值.
在您的示例中,数组迭代器确实会生成数组中的所有值(忽略非索引属性).
Ali*_*ahi 197
我在以下网址找到了完整的答案:https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html(虽然它是用于类型脚本,但对于javascript也是如此)
两个
for..of和for..in语句都遍历列表; 迭代的值虽然不同,但for..in返回正在迭代的对象上的键列表,而for..of返回正在迭代的对象的数值属性的值列表.以下示例说明了这种区别:
Run Code Online (Sandbox Code Playgroud)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" }另一个区别是for..in可以操作任何物体; 它用作检查此对象的属性的方法.
for..of另一方面,主要是对可迭代对象的值感兴趣.内置对象(如Map和Setimplement Symbol.iterator属性)允许访问存储的值.Run Code Online (Sandbox Code Playgroud)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" }
Ela*_*lar 34
在为...在循环,消除计数逻辑和退出条件在for循环的弱点得到改善.
例:
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const index in digits) {
console.log(digits[index]);
}
Run Code Online (Sandbox Code Playgroud)
但是,您仍然需要处理使用索引来访问数组值的问题,这很糟糕; 它几乎使它比以前更混乱.
此外,当你需要向数组(或另一个对象)添加额外的方法时,for ... in循环会让你遇到大麻烦.因为for ... 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]);
}
Run Code Online (Sandbox Code Playgroud)
打印:
0
1
2
3
4
五
6
7
8
9
function(){for(let i = 0; i <this.length; i ++){this [i] = this [i] .toFixed(2); }}
这就是为什么在循环数组时不鼓励使用in循环.
注意:forEach循环是JavaScript中的另一种for循环.但是,
forEach()实际上是一个数组方法,因此它只能与数组一起使用.也无法停止或中断forEach循环.如果在循环中需要这种类型的行为,则必须使用基本的for循环.
在对...的循环用于遍历任何类型的数据是可迭代.
例:
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
for (const digit of digits) {
console.log(digit);
}
Run Code Online (Sandbox Code Playgroud)
打印:
0
1
2
3
4
五
6
7
8
9
这使得for循环成为所有for循环中最简洁的版本.
但等等,还有更多!for循环还有一些额外的好处,可以解决for和for循环的弱点.
您可以随时停止或中断for循环.
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);
}
Run Code Online (Sandbox Code Playgroud)
打印:
1
3
五
7
9
而且您不必担心向对象添加新属性.for ... of循环只会遍历对象中的值.
Ale*_*ine 30
for of用于迭代可迭代对象并for in用于迭代对象属性
这里有一个要记住的技巧:
for of不适用于对象(所以它适用于可迭代对象)
for in不适用于i terables(所以它适用于对象)
另一个技巧:
for in返回骰子(键)中的for of对象,同时返回值
bni*_*and 21
这是一个有用的助记符,用于记住for...inLoop 和for...ofLoop之间的区别。
“索引,对象”
for...in Loop=> 迭代数组中的索引。
for...of Loop=> 迭代对象的对象。
小智 21
//for in,迭代对象中的键和数组中的索引
let obj={a:1, b:2}
for( const key in obj)
console.log(obj[key]); //would print 1 and 2
console.log(key); //would print a and b
let arr = [10, 11, 12, 13];
for (const item in arr)
console.log(item); //would print 0 1 2 3
Run Code Online (Sandbox Code Playgroud)
//for of,迭代数组或任何可迭代对象中的值
let arr = [10, 11, 12, 13];
for (const item of arr )
console.log(item); //would print 10 11 12 13
Run Code Online (Sandbox Code Playgroud)
小智 16
简短的回答:for...in循环键,而for...of循环值。
for (let x in ['a', 'b', 'c', 'd'] {
console.log(x);
}
// Output
0
1
2
3
for (let x of ['a', 'b', 'c', 'd'] {
console.log(x);
}
// Output
a
b
c
d
Run Code Online (Sandbox Code Playgroud)
sim*_*eco 10
两个循环之间的另一个区别,之前没有人提到过:
拆解
for...in已被弃用。使用for...of来代替。
所以如果我们想在循环中使用解构,为了获取每个数组元素的索引和值,我们应该使用带有Array方法的循环:for...ofentries()
for (const [idx, el] of arr.entries()) {
console.log( idx + ': ' + el );
}
Run Code Online (Sandbox Code Playgroud)
for..in和for..of:既for..in和for..of被循环其在数据结构用于迭代构建体。唯一的区别在于它们的迭代方式:
for..in遍历对象的所有可枚举的属性键for..of迭代一个可迭代对象的值。可迭代对象的示例是数组,字符串和NodeLists。let arr = ['el1', 'el2', 'el3'];
arr.addedProp = 'arrProp';
// elKey are the property keys
for (let elKey in arr) {
console.log(elKey);
}
// elValue are the property values
for (let elValue of arr) {
console.log(elValue)
}Run Code Online (Sandbox Code Playgroud)
在此示例中,我们可以观察到for..in循环遍历对象的键,该对象在此示例中是数组对象。键是0、1、2,它们对应于我们添加的数组元素和addedProp。这是arrchrome devtools中数组对象的外观:
您会看到我们的for..in循环只不过是迭代这些值而已。
在for..of我们的例子循环迭代值的数据结构。此特定示例中的值为'el1', 'el2', 'el3'。可迭代数据结构将使用的返回for..of值取决于可迭代对象的类型。例如,数组将返回所有数组元素的值,而字符串将返回字符串的每个单独字符。
请记住,它for in用于对象,而它for of用于数组、字符串等。
但是,您甚至不需要使用for in. 您始终可以使用for of:
const person = {name: 'John', age: 31};
for (let key in person) {
console.log(key, ': ', person[key]); // name: John
} // age: 31
for (let [key, value] of Object.entries(person)) {
console.log(key, ': ', value); // The same output
}
Run Code Online (Sandbox Code Playgroud)
小智 8
该for...in语句以任意顺序遍历对象的可枚举属性。可枚举属性是内部[[Enumerable]]标志设置为true的那些属性,因此,如果原型链中有任何可枚举的属性,则for...in循环也将在这些属性上进行迭代。
该for...of语句对可迭代对象定义要迭代的数据进行迭代。
例:
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
}
Run Code Online (Sandbox Code Playgroud)
与早期的,你可以跳过添加hasOwnProperty的for...of循环。
小智 7
for-in语句以任意顺序迭代对象的可枚举属性.
循环将遍历对象本身的所有可枚举属性以及对象从其构造函数的原型继承的属性
您可以将其视为"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"]
Run Code Online (Sandbox Code Playgroud)
小智 6
有些已经定义的数据类型使我们可以轻松地对其进行迭代,例如数组,映射,字符串对象
普通的for迭代迭代器,作为响应,为我们提供了按插入顺序排列的键,如以下示例所示。
const numbers = [1,2,3,4,5];
for(let number in number) {
console.log(number);
}
// result: 0, 1, 2, 3, 4
Run Code Online (Sandbox Code Playgroud)
现在,如果我们对for进行相同的尝试,那么作为响应,它将为我们提供值而不是键。例如
const numbers = [1,2,3,4,5];
for(let numbers of numbers) {
console.log(number);
}
// result: 1, 2, 3, 4, 5
Run Code Online (Sandbox Code Playgroud)
因此,查看两个迭代器,我们可以轻松地区分两者之间的差异。
注: - 对于只能与Symbol.iterator
因此,如果我们尝试遍历普通对象,那么它将给我们带来错误,例如-
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);
}
Run Code Online (Sandbox Code Playgroud)
房间不是可重复的
现在进行迭代,我们需要定义一个ES6 Symbol.iterator,例如
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
Run Code Online (Sandbox Code Playgroud)
这是For in和For of之间的区别。希望它可以清除差异。
小智 6
for...of循环仅适用于可迭代对象。在 JavaScript 中,可迭代对象是可以循环的对象。
String、Array、TypedArray、Map 和 Set 都是内置的可迭代对象,因为它们的每个原型对象都实现了 @@iterator 方法。因此,for...of 循环适用于提到的对象类型。
JavaScript 中的对象默认是不可迭代的。因此,for...of 循环不适用于对象。
简而言之,for...of 适用于字符串和数组,但不适用于对象。
为...在适用于可枚举标志设置为 true 的属性。
通过简单赋值或属性初始值设定项创建的属性的枚举标志默认为 true。通过 Object.defineProperty 创建的属性的可枚举标志默认为 false。
这是带有示例的更详细的帖子:https://dev.to/swastikyadav/difference- Between-forof-and-forin-loop-in-javascript-j2o
for-in环for-in循环用于以任意顺序遍历集合的可枚举属性。集合是一个容器类型对象,其项目可以使用索引或键。
var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];
var myString = "123";
console.log( myObject[ 'a' ], myArray[ 1 ], myString[ 2 ] );Run Code Online (Sandbox Code Playgroud)
for-in循环一次性提取集合的可枚举属性(键)并一次迭代一个。可枚举属性是可以出现在for-in循环中的集合的属性。
默认情况下,数组和对象的所有属性都出现在for-in循环中。但是,我们可以使用Object.defineProperty方法手动配置集合的属性。
var myObject = {a: 1, b: 2, c: 3};
var myArray = [1, 2, 3];
Object.defineProperty( myObject, 'd', { value: 4, enumerable: false } );
Object.defineProperty( myArray, 3, { value: 4, enumerable: false } );
for( var i in myObject ){ console.log( 'myObject:i =>', i ); }
for( var i in myArray ){ console.log( 'myArray:i =>', i ); }Run Code Online (Sandbox Code Playgroud)
在上面的例子中,属性d的myObject和指数3的myArray未出现在for-in,因为它们与配置循环enumerable: false。
for-in循环问题很少。在数组的情况下,for-in循环也会考虑methods使用myArray.someMethod = f语法添加到数组上,但是,myArray.length仍然是4。
for-of环for-of循环迭代集合的值是一种误解。for-of循环遍历一个Iterable对象。一个可迭代对象是一个对象,该对象Symbol.iterator在其原型之一上直接具有带有名称的方法。
Symbol.iterator方法应该返回一个Iterator。迭代器是一个拥有next方法的对象。此方法在调用返回value和done属性时。
当我们使用循环迭代一个可迭代对象时for-of,Symbol.iterator该方法将在获得迭代器对象后被调用。对于每一个迭代for-of循环,next该迭代器对象的方法将被调用,直到done在返回next()调用返回false。for-of如果调用value返回的属性,则每次迭代循环接收的值next()。
var myObject = { a: 1, b: 2, c: 3, d: 4 };
// make `myObject` iterable by adding `Symbol.iterator` function directlty on it
myObject[ Symbol.iterator ] = function(){
console.log( `LOG: called 'Symbol.iterator' method` );
var _myObject = this; // `this` points to `myObject`
// return an iterator object
return {
keys: Object.keys( _myObject ),
current: 0,
next: function() {
console.log( `LOG: called 'next' method: index ${ this.current }` );
if( this.current === this.keys.length ){
return { done: true, value: null }; // Here, `value` is ignored by `for-of` loop
} else {
return { done: false, value: _myObject[ this.keys[ this.current++ ] ] };
}
}
};
}
// use `for-of` loop on `myObject` iterable
for( let value of myObject ) {
console.log( 'myObject: value => ', value );
}Run Code Online (Sandbox Code Playgroud)
该for-of回路处于ES6新等都是可迭代和Iterables。该Array构造类型都有Symbol.iterator它的原型方法。Object遗憾的是,构造函数没有它 but Object.keys(),Object.values()并且Object.entries()方法返回一个可迭代对象(您可以console.dir(obj)用来检查原型方法)。for-of循环的好处是任何对象都可以迭代,甚至是你的自定义Dog和Animal类。
使对象可迭代的简单方法是实现ES6 Generator而不是自定义迭代器实现。
与 不同for-in,for-of循环可以在每次迭代中等待异步任务完成。这是await在for语句文档之后使用关键字实现的。
for-of循环的另一个优点是它支持 Unicode。根据 ES6 规范,字符串以 UTF-16 编码存储。因此,每个字符都可以使用16-bit或32-bit。传统上,字符串使用 UCS-2 编码存储,该编码支持只能存储在其中的字符16 bits。
因此,String.length返回16-bit字符串中的块数。像表情符号这样的现代字符需要 32 位。因此,这个字符将返回length2.for-in循环遍历16-bit块并返回错误的index。但是,for-of循环会根据 UTF-16 规范迭代单个字符。
var emoji = "";
console.log( 'emoji.length', emoji.length );
for( var index in emoji ){ console.log( 'for-in: emoji.character', emoji[index] ); }
for( var character of emoji ){ console.log( 'for-of: emoji.character', character ); }Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
134167 次 |
| 最近记录: |