while
while(){
//......
}
do-while
do{
//......
}while(){
//......
}
for
for(var i = 0; i < array.length; i++){
//......
}
forEach
// currentValue 当前元素
// index 当前元素的索引值。
// arr 当前元素所属的数组对象。
// thisValue 传递给函数的值一般用 "this" 值。如果这个参数为空, "undefined" 会传递给 "this" 值
objArr.forEach(function(currentValue, index, arr){
console.log(value);
}, thisValue);
// IE 8及更早版本不支持
// 用 forEach 遍历数组的话,不能中断循环(使用 break 或者 return)
// 如果要提前终止,必须把 forEach() 方法放在一个 try 块中,并能抛出一个异常。如果 forEach()调用的函数抛出 foreach.break 异常,循环会提前终止
function foreach(a, f, t){
try {
a.forEach(f,t)
}catch(e){
if(e === foreach.break)return;
else throw e;
}
}
foreach.break = new Error("StopIteration");
forEach 还有其他问题请参考:https://zhuanlan.zhihu.com/p/614624783?utm_id=0
for-in
// 所有浏览器都支持
for-in 语句用于遍历对象或者数组的属性(键名)
let es6 = {
edition: 6,
committee: "TC39",
standard: "ECMA-262"
};
for (let e in es6) {
console.log(e); // edition committee standard
console.log(es6[e]); // 6 TC39 ECMA-262
}
let objArr = [ 'a', 'b', 'c' ];
for(var index in objArr){
console.log(index) // 0 1 2
console.log(objArr[index]) // a b c
}
`for-in 循环实际是为循环 ”enumerable“ 对象而设计的`
**** 数组上不建议使用 for-in 循环 ****
以上代码会出现的问题:
1.index 值是字符串(String)类型,可能无意间进行字符串的计算 “2” + 1 = “21” 等,所以不能直接进行几何运算
2.循环不仅会遍历数组元素,还会遍历任意其他自定义添加的属性,如,objArr上 面包含自定义属性,objArr.name,那这次循环中也会出现此 name 属性
3.某些情况下,上述代码会以随机顺序循环数组
for-of
// currentValue 必须。当前元素的值
for(let currentValue of objArr){
console.log(currentValue)
}
JavaScript6 里引入了一种新的循环方法,它就是 for-of 循环,它既比传统的 for 循环简洁,同时弥补了 forEach 和 for-in 循环的短板
如果循环普通对象,会报错 // TypeError: es6[Symbol.iterator] is not a function 或者 // Uncaught TypeError: es6 is not iterable
解决方法是,使用 Object.keys 方法将对象的键名生成一个数组,然后遍历这个数组
for (let key of Object.keys(someObject)) {
console.log(key + ': ' + someObject[key]);
}
如果使用 for of 想要获取当前索引值
var arr = [ 'a', 'b', 'c' ];
for( let [ index, currentValue ] of new Map( arr.map( ( item, i ) => [ i, item ] ) ) ) {
console.log(index, currentValue);
}
或者
for( let [ index, currentValue ] of arr.entries() ) {
console.log(index, currentValue);
}
`for-of 可以使用 break、continue 、return 退出循环`
`for-of 主要遍历 可迭代对象(iterable)`
for-of 可以循环遍历很多东西
1、循环一个数组(Array)
2、循环一个字符串
3、循环一个类型化的数组(TypedArray)
4、循环一个 Map
5、循环一个 Set
6、循环一个 DOM collection(节点)
7、循环一个拥有 enumerable 属性的对象
8、循环一个生成器(generators)
map
// currentValue 必须。当前元素的值
// index 可选。当前元素的索引值
// arr 可选。当前元素属于的数组对象
// thisValue 对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。
array.map(function(currentValue, index, arr), thisValue)
// IE 8及更早版本不支持
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let newArr = arr.map(item => item * 2);
console.log(newArr) // [2, 4, 6, 8, 10, 12, 14, 16, 18]
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改原始数组。
filter
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
array.filter(function(currentValue, index, arr), thisValue)
// IE 8及更早版本不支持
var ages = [32, 33, 16, 40];
let newAges = ages.filter(function(currentValue){
return currentValue >= 18;
})
console.log(newAges) // [32, 33, 40]
// 移除数组中所有的 ”false“ 类型元素
let b = a.filter(Boolean)
// 等同于
let b = a.filter(function(x) { return Boolean(x); })
find
array.find(function(currentValue, index, arr),thisValue)
find() 方法返回通过测试(函数内判断)的数组的第一个元素的值
find() 方法为数组中的每个元素都调用一次函数执行
当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数
如果没有符合条件的元素返回 undefined
注意: find() 对于空数组,函数是不会执行的
注意: find() 并没有改变数组的原始值
注意: IE 11 及更早版本不支持 find() 方法
var ages = [3, 10, 18, 20];
function checkAdult(age) {
return age >= 18;
}
function myFunction() {
document.getElementById("demo").innerHTML = ages.find(checkAdult); // 18
}
findIndex
array.findIndex(function(currentValue, index, arr), thisValue)
findIndex() 方法返回传入一个测试条件(函数)符合条件的数组第一个元素位置
findIndex() 方法为数组中的每个元素都调用一次函数执行
当数组中的元素在测试条件时返回 true 时, findIndex() 返回符合条件的元素的索引位置,之后的值不会再调用执行函数
如果没有符合条件的元素返回 -1
注意: findIndex() 对于空数组,函数是不会执行的
注意: findIndex() 并没有改变数组的原始值
注意: IE 11 及更早版本不支持 findIndex() 方法
var ages = [3, 10, 18, 20];
function checkAdult(age) {
return age >= 18;
}
function myFunction() {
document.getElementById("demo").innerHTML = ages.findIndex(checkAdult); // 2
}
some、every
var resSome = array.some(function(currentValue, index, arr),thisValue)
// IE 8及更早版本不支持
some() 方法用于检测数组中的元素是否满足指定条件(函数提供)
some() 方法会依次执行数组的每个元素
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测
如果没有满足条件的元素,则返回false
注意: some() 不会对空数组进行检测
注意: some() 不会改变原始数组
var resEvery = array.every(function(currentValue, index, arr), thisValue)
// IE 8及更早版本不支持
every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)
every() 方法使用指定函数检测数组中的所有元素
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测
如果所有元素都满足条件,则返回 true
注意: every() 不会对空数组进行检测
注意: every() 不会改变原始数组
reduce、reduceRight
// total 必需。initialValue 的初始值, 或者计算结束后的返回值
// currentValue 必需。当前元素
// currentIndex 可选。当前元素的索引
// arr 可选。当前元素所属的数组对象
// initialValue 可选。传递给函数的初始值
array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
// IE 8及更早版本不支持
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值
reduce() 可以作为一个高阶函数,用于函数的 compose
注意: reduce() 对于空数组是不会执行回调函数的
let arr = [1, 2, 3];
let ad = arr.reduce(function(i, j){
return i + j;
})
reduceRight 和 reduce 相反,是从右到左
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
})
console.log(arr, sum);
上面的例子索引是从 1 开始的,第一次的 prev 的值是数组的第一个值。数组长度是 4,但是 reduce 函数循环 3次
var arr = [1, 2, 3, 4];
var sum = arr.reduce(function(prev, cur, index, arr) {
console.log(prev, cur, index);
return prev + cur;
}, 0);
console.log(arr, sum);
如果没有提供 initialValue,reduce 会从索引 1 的地方开始执行 callback 方法,跳过第一个索引
如果提供 initialValue,reduce 会从索引 0 的地方开始,reduce 函数循环 4次
求和
var arr = [1, 2, 3, 4];
var sum = arr.reduce((x, y) => x + y)
console.log(sum); // 10
求乘积
var arr = [1, 2, 3, 4];
var mul = arr.reduce((x, y) => x * y)
console.log(mul); // 24
计算数组中每个元素出现的次数
let names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
let nameNum = names.reduce((pre, cur) => {
if(cur in pre){
pre[cur]++
}else{
pre[cur] = 1;
}
return pre
}, {});
console.log(nameNum); // { Alice: 2, Bob: 1, Tiff: 1, Bruce: 1 }
数组去重
let arr = [1, 2, 3, 4, 4, 1];
let newArr = arr.reduce((pre, cur) => {
if(!pre.includes(cur)){
return pre.concat(cur);
}else{
return pre;
}
}, []);
console.log(newArr); // [1, 2, 3, 4]
将二维数组转化为一维
let arr = [[0, 1], [2, 3], [4, 5]]
let newArr = arr.reduce((pre, cur) => {
return pre.concat(cur)
},[])
console.log(newArr); // [0, 1, 2, 3, 4, 5]
将多维数组转化为一维
let arr = [[0, 1], [2, 3], [4, [5, 6, 7]]]
const newArr = function(arr){
return arr.reduce((pre, cur) => pre.concat(Array.isArray(cur) ? newArr(cur) : cur), [])
}
console.log(newArr(arr)); // [0, 1, 2, 3, 4, 5, 6, 7]
对象里的属性求和
var result = [
{
subject: 'math',
score: 10
},
{
subject: 'chinese',
score: 20
},
{
subject: 'english',
score: 30
}
];
var sum = result.reduce(function(prev, cur) {
return cur.score + prev;
}, 0);
console.log(sum) // 60
数组转对象
const list = [
{ name: 'yzw', area: 'gz', age: 27, sex: '男' },
{ name: 'tyj', area: 'sz', age: 24, sex: '女' }
];
const map = list.reduce((prev, cur) => {
const { name, ...rest } = cur;
prev[name] = rest;
return prev;
}, {});
console.log(map);
// {
// tyj: { area: 'sz', age: 24, sex: '女' }
// yzw: { area: 'gz', age: 27, sex: '男' }
// }
Object.keys() 遍历对象的属性名,返回一个数组
let obj = { foo: 'bar', baz: 42 };
Object.keys(obj) // ["foo", "baz"]
Object.values() 遍历对象的属性值,返回一个数组
let obj = { foo: 'bar', baz: 42 };
Object.values(obj) // ["bar", 42]
Object.entries() 遍历对象的属性的键值对数组,返回一个数组
let obj = { foo: 'bar', baz: 42 };
Object.entries(obj) // [ ["foo", "bar"], ["baz", 42] ]
Object.fromEntries() 是 Object.entries() 的逆操作,将一个键值对数组转为对象
Object.fromEntries([
['foo', 'bar'],
['baz', 42]
])
// { foo: "bar", baz: 42 }
Object.getOwnPropertyNames() 遍历对象的属性
Object.getOwnPropertyKeys() 遍历对象的属性值