一次性讲清JS中的所有for循环

发布于:2024-05-06 ⋅ 阅读:(17) ⋅ 点赞:(0)
  • for
  • for of
  • for in
  • forEach
  • map
  • every
  • reduce
  • set

讲一下for…of

for...of 是 JavaScript 的一种循环语法,用于遍历可迭代对象 (如数组、字符串、Set、Map 等) 中的元素。它提供了一种简洁的方式来遍历集合中的元素,而无需使用传统的索引迭代方式。

以下是 for...of 循环的基本语法:

for (variable of iterable) {
  // 在每次迭代中执行的代码
  // 学习一下单词 statement 语句
  // outline 提纲;目录
}
  • variable:变量,用于存储当前迭代的值。在每次循环迭代时,将会自动赋值为可迭代对象中的当前元素。
  • iterable:可迭代对象,即要遍历的集合。它可以是数组、字符串、Set、Map 等实现了迭代器接口的对象。

在每次迭代时,for...of 语句会将 iterable 中的下一个元素赋值给 variable,直到遍历完所有元素为止。

以下是使用 for...of 循环遍历数组的示例:

var colors = ['red', 'green', 'blue'];

for (var color of colors) {
  console.log(color);
}

在上述示例中,for...of 循环会依次遍历数组 colors 中的每个元素,并将当前元素赋值给变量 color。然后,在循环体中,可以对 color 进行操作,比如打印它的值。

for...of 循环的优点包括:

  • 简洁:无需处理索引或使用额外的计数器变量。
  • 自动迭代:根据迭代对象的特性,它会自动迭代元素并赋值给变量。
  • 适用于可迭代对象:可以用于遍历各种可迭代对象,而不仅限于数组。

需要注意的是,for...of 循环不适用于普通对象(Plain Object),因为普通对象不是可迭代对象。若需要遍历普通对象的属性,可以使用 for...in 循环。

总结:for...of 是 JavaScript 中一种用于遍历可迭代对象的循环语法。它提供了一种简洁、直观的方式来遍历集合中的元素,而无需使用索引。它适用于数组、字符串、Set、Map 等实现了迭代器接口的对象。

可迭代是什么意思

可迭代对象(iterable)是指实现了迭代器协议的对象,即实现了 Symbol.iterator 方法的对象。迭代器协议定义了一种标准的方式,使得对象可以被迭代,也就是说可以用 for...of 循环遍历。

一些内置对象,例如 ArrayStringMapSet 等都是可迭代对象,因为它们都实现了 Symbol.iterator 方法。同时,我们也可以自己实现一个可迭代对象,只需要在对象上定义一个 Symbol.iterator 方法,该方法返回一个迭代器(iterator)对象,该对象必须实现一个 next() 方法,以便迭代器可以按顺序访问该对象的所有元素。

讲一下for…in

for...in 是 JavaScript 的一种循环语法,用于遍历对象的可枚举属性 (Enumerable===true)。它提供了一种遍历对象属性的简洁方式,可以用于遍历普通对象和数组等。

以下是 for...in 循环的基本语法:

for (variable in object) {
  // 在每次迭代中执行的代码
}
  • variable:变量,用于存储当前迭代的属性名。在每次循环迭代时,将会自动赋值为对象的一个可枚举属性名。
  • object:对象,即要遍历的对象。

以下是使用 for...in 循环遍历对象的示例:

var person = {
  name: 'Alice',
  age: 30,
  profession: 'Engineer'
};

for (var key in person) {
  console.log(key + ': ' + person[key]);
}

在上述示例中,for...in 循环会遍历对象 person 中的每个可枚举属性,并将当前属性名赋值给变量 key。然后,在循环体中,可以通过 person[key] 来访问该属性的值。

需要注意的是,for...in 循环遍历的是对象的可枚举属性,包括对象自身的属性以及从原型链继承的属性。若只需遍历对象自身的属性而不包括继承的属性,可以使用 hasOwnProperty() 方法进行过滤

var person = new Object({
    name: "Alice",
    age: 30,
    profession: "Engineer",
});

Object.prototype.height = 185; // 定义在原型链上

for (var key in person) {
    if (person.hasOwnProperty(key)) { // 这里如果没有hasOwnProperty判断,会打印height键值
        console.log(key + ": " + person[key]);
    }
}

此外,for...in 循环也可用于遍历数组的索引或对象属性的动态访问。

总结:for...in 是 JavaScript 中一种用于遍历对象可枚举属性的循环语法。它提供了一种简洁的方式来遍历对象的属性,可以用于遍历普通对象和数组等。需要注意的是,它会遍历对象自身的属性以及从原型链继承的属性。

for...of和for...in的区别

  • for...of 循环:

    • 遍历的是可迭代对象(iterable),例如数组、字符串、Set、Map 等。

    • 迭代的是对象的而不是键。

    • 遍历顺序是按照对象的迭代顺序进行的,如数组的索引顺序或字符串的字符顺序。

    • 不支持遍历普通对象(plain objects),因为普通对象不是可迭代对象。

    • var arr = [1, 2, 3];
      
      for (var value of arr) {
        console.log(value);
      }
      
      //输出结果:
      1
      2
      3
      
  • for...in 循环:

    • 遍历的是对象的可枚举属性

    • 迭代的是对象的而不是值。

    • 遍历顺序是不确定的,可能不会按照对象属性的顺序进行遍历。

    • 可以遍历普通对象的可枚举属性,也可以遍历数组等对象的非索引属性。

    • var obj = { a: 1, b: 2, c: 3 };
      
      for (var key in obj) {
        console.log(key + ': ' + obj[key]);
      }
      
      //输出结果:
      a: 1
      b: 2
      c: 3
      

讲一下forEach

forEach() 是 JavaScript 数组对象的一个内置方法,用于遍历数组中的每个元素,并对每个元素执行回调函数。(在原数组上进行操作且没有返回值)

正常情况下,应该避免在 forEach() 方法中修改原始数组的元素,因为它的主要目的是遍历数组而不是修改数组。如果需要对每个元素进行转换或操作,并生成一个新的数组,可以使用 map() 方法。

forEach() 方法接受一个回调函数作为参数,该回调函数会在数组的每个元素上被调用。回调函数会接收三个参数:当前元素的值、当前元素的索引和被遍历的数组本身。

以下是 forEach() 方法的基本语法:

array.forEach(callback(currentValue, index, array), thisArg)
  • callback:回调函数,用于对数组的每个元素进行操作。它可以接受三个参数:
    • currentValue:当前遍历到的元素的值。
    • index:当前遍历到的元素的索引。
    • array(可选):原始数组。
  • thisArg(可选):回调函数中的 this 值。

下面是一个示例,展示了如何使用 forEach() 方法对数组中的每个元素进行打印操作:

var numbers = [1, 2, 3, 4, 5];

numbers.forEach(function(element, index) {
  console.log(`当前元素是 ${element},索引是 ${index}`);
});
// 尽管回调函数在代码中定义了三个参数,但只使用了前两个参数。第三个参数 arr 是可选的,可以选择在回调函数的实现中忽略它。

在上述示例中,回调函数会在数组 numbers 的每个元素上被调用。它会打印出当前元素的值和索引。循环会依次遍历数组中的每个元素,对每个元素执行回调函数。

forEach() 方法遍历数组时,会自动跳过稀疏数组中的空位(undefined)。它会按照数组元素的顺序依次执行回调函数,直到遍历完所有元素为止。

需要注意的是,forEach() 方法没有返回值,它只是对每个元素执行回调函数。如果需要生成一个新的数组,可以使用 map() 方法。

总结:forEach() 方法用于遍历数组中的每个元素,并对每个元素执行回调函数。它没有返回值,只是对原数组元素进行操作。通过回调函数,可以访问当前元素的值和索引,以及原始数组。

讲一下map()

在 JavaScript 中,map()数组对象的一个内置方法,用于对数组中的每个元素进行操作,并返回一个新的数组。它会遍历原始数组中的每个元素,对每个元素应用回调函数,并将回调函数的返回值组成一个新的数组。(不会修改原数组内容)

map() 方法接受一个回调函数作为参数,该回调函数会在数组的每个元素上被调用,并返回新数组中的对应元素。

以下是 map() 方法的基本语法:

array.map(callback(element, index, array), thisArg)
  • callback:回调函数,用于对数组的每个元素进行操作。它可以接受三个参数:
    • element:当前遍历到的元素。
    • index:当前遍历到的元素的索引。
    • array:原始数组。
  • thisArg(可选):回调函数中的 this 值。

下面是一个示例,展示了如何使用 map() 方法将数组中的每个元素乘以 2,并生成一个新的数组:

var numbers = [1, 2, 3, 4, 5];

var doubledNumbers = numbers.map(function(element) {
  return element * 2;
});

console.log(doubledNumbers);  // 输出:[2, 4, 6, 8, 10]

在上述示例中,回调函数将每个元素乘以 2,并将结果作为新数组中的对应元素。因此,doubledNumbers 数组包含了原始数组中的每个元素乘以 2 的结果。

需要注意的是,map() 方法不会修改原始数组,而是返回一个新的数组。因此,它是一种纯函数,不会产生副作用。

另外,如果数组中的元素是对象,map() 方法仅对对象的引用进行操作,不会进行深层复制。所以在对对象数组进行 map() 操作时,需要注意对原始对象的引用和副本的处理

总结:map() 方法是数组的内置方法,用于对数组中的每个元素进行操作,并返回一个新的数组。它通过应用回调函数对每个元素进行转换来生成新的数组。

map()跟foreach有什么区别

  • map()
    • 返回一个回调函数处理后的新数组
    • 对原数组没有影响
    • 目的:处理数组数据
  • forEach
    • 没有返回值,不会生成新数组
    • 无法修改原数组
    • 目的:遍历数组

讲一下every()

Array.prototype.every() 方法,它可以用于检查数组中的所有元素是否满足特定条件。

every() 方法接受一个回调函数作为参数,该回调函数会在数组的每个元素上被调用,并根据返回值判断是否继续遍历数组。如果回调函数对于每个元素都返回 true,则 every() 方法返回 true。如果回调函数对于任何一个元素返回 false,则 every() 方法立即返回 false不再继续遍历剩余的元素

以下是 every() 方法的基本语法:

array.every(callback(element, index, array), thisArg)
  • callback:回调函数,用于对数组的每个元素进行操作。它可以接受三个参数:
    • element:当前遍历到的元素。
    • index:当前遍历到的元素的索引。
    • array:原始数组。
  • thisArg(可选):回调函数中的 this 值。

下面是一个示例,展示了如何使用 every() 方法检查数组中的所有元素是否为偶数:

var numbers = [2, 4, 6, 8, 10];

var allEven = numbers.every(function(element) {
  return element % 2 === 0;
});

console.log(allEven);  // 输出:true

在上述示例中,回调函数检查每个元素是否为偶数。由于数组中的所有元素都是偶数,所以 every() 方法返回 true

需要注意的是,如果数组为空,every() 方法将始终返回 true,因为没有元素不满足条件。此外,every() 方法只要找到一个不满足条件的元素就会立即停止遍历剩余的元素。

讲一下reduce()

reduce() 是数组方法之一,用于对数组的元素进行累积计算。它接受一个回调函数作为参数,并可以传递一个初始值。这个回调函数会被应用到数组的每个元素上,从左到右进行迭代,将前一个回调函数的返回值作为下一个回调函数的输入,最终得到一个累积的结果。

reduce() 方法的语法如下:

array.reduce(callback, initialValue)
  • callback 是一个回调函数,它可以接受四个参数:
    • accumulator:累积器,用于保存计算的中间结果。
    • currentValue:当前元素的值。
    • currentIndex:当前元素的索引(可选)。
    • array:被迭代的数组(可选)。 回调函数应该返回一个新的累积值,它将作为下一次迭代的 accumulator 值。
  • initialValue 是可选的,用于指定累积的初始值。如果没有提供初始值,则将使用数组的第一个元素作为初始值,并从第二个元素开始进行迭代。

reduce() 方法的使用示例:

const array = [1, 2, 3, 4, 5];

const sum = array.reduce((accumulator, currentValue) => {
  return accumulator + currentValue;
}, 0);
// 这里传入的实参0是可选参数initialValue,用于指定累积的初始值
// 如果没有提供初始值,则将使用数组的第一个元素作为初始值,并从第二个元素开始进行迭代。
// 所以不写也是OK的,结果相同

console.log(sum); // 输出 15

在上述示例中,reduce() 方法对数组 array 中的元素进行累加求和,初始值设置为 0。回调函数接受两个参数,accumulator 为累加器,currentValue 为当前元素的值。每次迭代时,回调函数将当前元素的值加到累加器上,并返回新的累加值。最终得到的结果是数组元素的总和,即 15

讲一下set

在 JavaScript 中,Set 是一种集合数据结构,用于存储唯一的值,即集合中的每个元素都是唯一的,不会重复。它是 ES6(ECMAScript 2015)引入的一种数据结构,提供了一组方法用于管理集合中的元素。

以下是 Set 的基本特点和用法:

  1. 存储唯一值:Set 中的元素是唯一的,不会重复。如果尝试向集合中添加重复的值,将被忽略。
  2. 任意类型的值:Set 可以存储任意类型的值,包括原始类型(如数字、字符串、布尔值)、对象、函数等。
  3. 迭代器:Set 是可迭代的,可以使用 for...of 循环或 forEach() 方法遍历集合中的元素。
  4. 添加和删除元素:
    • 添加元素:使用 add(value) 方法向集合中添加新元素。
    • 删除元素:使用 delete(value) 方法从集合中删除指定的元素。
    • 清空集合:使用 clear() 方法清空集合中的所有元素。
  5. 判断元素是否存在:
    • 使用 has(value) 方法可以检查集合中是否存在指定的元素。返回值为布尔类型。

下面是一个使用 Set 的示例:

var set = new Set();

set.add(1);      // 添加元素
set.add(2);
set.add(3);
set.add(2);      // 重复的元素将被忽略

console.log(set.size);  // 输出:3

set.delete(2);   // 删除元素

console.log(set.size);  // 输出:2
console.log(set.has(3)); // 输出:true

set.forEach(function(value) {
  console.log(value);  // 依次输出:1, 3
});

需要注意的是,Set 中的值是根据严格相等性(===)来进行比较的,因此对于对象等引用类型的值,判断是否相等需要引用相同的对象。

总结:Set 是一种集合数据结构,用于存储唯一的值。它提供了添加、删除和判断元素是否存在的方法,以及迭代集合中的元素。Set 在需要存储唯一值且不关心顺序的情况下非常有用,可以帮助我们处理集合数据。

js中set会把元素按大小进行排序吗

在 JavaScript 的 Set 中,元素的顺序是根据插入顺序确定的,而不是按照大小进行排序。当你向 Set 添加元素时,它们将按照添加的顺序排列。

Set 的迭代顺序与元素的插入顺序相同。这意味着当你使用 for...of 循环或 forEach() 方法迭代 Set 时,元素的顺序将与添加它们的顺序保持一致。

以下是一个示例:

var set = new Set();

set.add(3);
set.add(1);
set.add(2);

set.forEach(function(value) {
  console.log(value);
});

输出的顺序将是 3, 1, 2与添加元素的顺序一致。

如果你需要按照某种特定顺序对元素进行排序,你可以将 Set 转换为数组,然后使用数组的排序方法对元素进行排序。例如:

var set = new Set();

set.add(3);
set.add(1);
set.add(2);

var sortedArray = Array.from(set).sort();

console.log(sortedArray);  // 输出: [1, 2, 3]

在上述示例中,首先使用 Array.from() 方法将 Set 转换为数组,然后使用数组的 sort() 方法对元素进行排序。这样,你可以获得一个按照元素大小排序的数组。

总结:Set 不会根据元素的大小进行排序,而是根据插入顺序进行排列。如果你需要对元素进行排序,可以将 Set 转换为数组,然后使用数组的排序方法。

#include <iostream>
#include <set>
using namespace std;

int main(){
	set<int> s;
	s.insert(3);
	s.insert(1);
	s.insert(2);
	for(set<int>::iterator i=s.begin();i!=s.end();i++){
		cout<<*i<<" "; // 结果:1 2 3
	}
	// 小结:c++的set容器会对插入的元素值的大小进行排序
	// 而JS则是按照插入的顺序进行排序 
	return 0;
} 

小结:c++的set容器会对插入的元素值的大小进行排序,而JS则是按照插入的顺序进行排序