1. for 循环
let arr = [1, 2, 3]
for(let i = 0; i < arr.length; i++){
console.log(arr[i])
}
2. forEach 方法
const arr1 = [1, 2, 3, 4, 5]; //声明数组
arr1.forEach(function(item) {
console.log(item) //item为每一项,不是每一项的索引(切记)
})
//使用箭头函数
arr1.forEach(item => {
console.log(item) //item为每一项,不是每一项的索引(切记)
})
这个语法看起来要简洁很多,不需要通过索引去访问数组项,但缺点也很明显,不支持break,continue等
[1,2,3,4,5].forEach(function(i){
if (i === 3) {
return; //return时,打印结果:1,2,4,5
//break; //break时,Uncaught SyntaxError: Illegal break statement(语法错误)
//continue; //continue时,Uncaught SyntaxError: Illegal continue statement: no surrounding iteration statement
} else {
console.log(i)
}
})
这段代码的 “本意” 是想从第一个元素开始遍历,遇到某一项等于3之后就结束遍历,否则打印出所遍历过的数组项。 可是结果却是 “违背本意” ,因为它的输出为 1,2,4,5
注意:forEach 的代码块中不能使用 break、continue,它会抛出异常。
array.forEach(function(item, index, arr), thisValue)
参数:
function(item, index, arr) 必需 ----- item: (必需)当前元素 index: (可选) 当前元素的索引值 arr: (可选)当前元素所属的对象
thisValue: 当执行回调函数 function 时,用作 this 的值。
返回值:
undefined (没有返回值)
3. every 方法
every
和forEach
使用方法一样,不同的是every
可以实现 break,continue 那样的效果。简单的说, return false 等同于 break, return true 等同于 continue, 如果不写, 默认是 return false
[1,2,3,4,5].every(function(i){
if (i === 3) {
return false
} else {
console.log(i)
return true //如果不写,默认是return false 结果为: 1
}
})
结果: 1, 2
注意: every 的代码块中不能使用 break、continue,它会抛出异常。
every() 方法测试一个数组内的所有元素是否都能通过某个指定函数的测试。它返回一个布尔值。
array.every(function(currentValue,index,arr), thisValue)
返回值:
布尔值。如果所有元素都通过检测返回 true,否则返回 false。
举例:
[32, 33, 16, 40].every(item => {
return item < 35
})
结果: false
4. filter 方法
filter()
方法创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。 不会改变原数组
const words = [1, 3, 4, 8, 5, 2];
const result = words.filter(word => {
word = word + 3
return word > 6
});
console.log(result); // > Array [4, 8, 5]
console.log(words) // > Array [1, 3, 4, 8, 5, 2]
可以用来筛选一个数组中符合条件的元素
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
参数:
callback: 用来测试数组的每个元素的函数。返回true表示该元素通过测试,保留该元素,false则不保留。 参数与forEach()和every()等相同
thisArg: 与forEach()和every()等相同
返回值:
一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。
5. map 方法
map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
const array1 = [1, 4, 9, 16];
const map1 = array1.map(function(item) {
return item * 2
})
//箭头函数
// const map1 = array1.map(item => item * 2);
console.log(map1); // 输出:[2, 8, 18, 32]
console.log(array1); //输出:[1, 4, 9, 16]
根据上述代码可以看出
map()
不会改变原数组,会返回一个新数组。下面举一个我经常在敲代码时用map()
实现的 看起来改变了原数组的例子
const personList = [
{name: 'aaa', age: 18},
{name: 'bbb', age: 23},
{name: 'ccc', age: 25}
]
// 看起来改变了原数组--修改(添加)对象数组中对象的某个属性
personList.map(item => { //使用forEach()也可以实现 将map替换为forEach
item.age += 1 // 修改
item.gender = '男' //添加
})
console.log(personList)
输出:
[
{name: "aaa", age: 19, gender: "男"},
{name: "bbb", age: 24, gender: "男"},
{name: "ccc", age: 26, gender: "男"}
]
原数组为什么看起来改变了呢?? 因为对象是引用类型,内存地址不变,这个对象就是不变的,而对对象的属性进行操作不会改变内存地址,所以原数组是没改变的
那用
map()
新生成的对象数组和原对象数组是不是浅拷贝呢???
const personList = [
{name: 'aaa', age: 18},
{name: 'bbb', age: 23},
{name: 'ccc', age: 25}
]
const newList = personList.map(item => {
item.age += 1
return item
})
console.log(newList) //[{name: "aaa", age: 19},{name: "bbb", age: 24},{name: "ccc", age: 26}]
console.log(personList) //[{name: "aaa", age: 19},{name: "bbb", age: 24},{name: "ccc", age: 26}]
新数组和原数组看起来一样,看一下改变新数组 ,原数组会改变吗?
newList[0].name = '哈哈哈哈哈哈'
console.log(newList) //[{name: "哈哈哈哈哈哈", age: 19},{name: "bbb", age: 24},{name: "ccc", age: 26}]
console.log(personList) //[{name: "哈哈哈哈哈哈", age: 19},{name: "bbb", age: 24},{name: "ccc", age: 26}]
根据结果可以看到,修改新数组会改变原数组
如何才能实现修改新数组不改变原数组呢????(使用 map 重新格式化数组中的对象)
const personList = [
{name: 'aaa', age: 18},
{name: 'bbb', age: 23},
{name: 'ccc', age: 25}
]
const newList = personList.map(item => {
const rObj = {}
rObj.name = item.name
rObj.age = item.age
return rObj
})
console.log(newList) //[{name: "aaa", age: 18},{name: "bbb", age: 23},{name: "ccc", age: 25}]
console.log(personList) //[{name: "aaa", age: 18},{name: "bbb", age: 23},{name: "ccc", age: 25}]
newList[0].name = '哈哈哈哈哈哈'
console.log(newList) //[{name: "哈哈哈哈哈哈", age: 18},{name: "bbb", age: 23},{name: "ccc", age: 25}]
console.log(personList) //[{name: "aaa", age: 18},{name: "bbb", age: 23},{name: "ccc", age: 25}]
这样改变新数组就不会改变原数组了
语法和
forEach()
类似
6. for ... in
var obj = {a:1, b:2, c:3};
for (var prop in obj) {
console.log("obj." + prop + " = " + obj[prop]);
}
// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
7. for ... of (重头戏)
for (let val of [1,2,3]) {
console.log(val);
}
// 1,2,3
- 有着同for...in一样的简洁语法,但是没有for...in那些缺点。
- 不同于forEach方法,它可以与break、continue和return配合使用。
- 提供了遍历所有数据结构的统一操作接口。
for (variable of iterable) {
//statements
}
迭代数组
let iterable = [10, 20, 30];
for (let value of iterable) {
value += 1;
console.log(value);
}
// 11
// 21
// 31
迭代String
let iterable = "boo";
for (let value of iterable) {
console.log(value);
}
// "b"
// "o"
// "o"
迭代Map
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]);
for (let entry of iterable) {
console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3]
for (let [key, value] of iterable) {
console.log(value);
}
// 1
// 2
// 3
迭代Set
let iterable = new Set([1, 1, 2, 2, 3, 3]);
for (let value of iterable) {
console.log(value);
}
// 1
// 2
// 3
迭代arguments 对象
(function() {
for (let argument of arguments) {
console.log(argument);
}
})(1, 2, 3);
// 1
// 2
// 3
for-of
和for-in
的区别
for-in
语句以原始插入顺序迭代对象的可枚举属性。for-in
会把继承链的对象属性都会遍历一遍,所以会更花时间.
for-of
语句只遍历可迭代对象的数据。