目录
1 数组
数组属于一种特殊的对象,键名就是整数 0、1、2。
- 除了在定义时赋值,数组也可以先定义后赋值。
- 如果数组的元素还是数组,就形成了多维数组。
var a = [
[1, 2],
[3, 4],
];
a[0][1]; // 2
a[1][1]; // 4
1.1 数组成员
1.1.1 属性
-
length
,返回数组的成员数量。是数组本身独有的属性 -
清空数组的一个有效方法,就是将
length
属性设为 0。 -
length 不是计算数组属性的长度,length 是计算数组下标最大的值+1
-
对象没有 length 属性,对象不能用 length 返回其拥有的属性对象
-
按照数组添加成员,数组本身更新
-
按照对象添加成员,不会触发数组的更新
1.1.2 delete
- 使用
delete
命令删除一个数组成员,会形成空位,并且不会影响length
属性。
var a = [1, 2, 3];
delete a[1];
a[1]; // undefined
a.length; // 3
- 上面代码用
delete
命令删除了数组的第二个元素,这个位置就形成了空位,但是对length
属性没有影响。也就是说,length
属性不过滤空位。所以,使用length
属性进行数组遍历,一定要非常小心。 - 数组的某个位置是空位,与某个位置是
undefined
,是不一样的。如果是空位,使用数组的forEach
方法、for...in
结构、以及Object.keys
方法进行遍历,空位都会被跳过。 - 这就是说,空位就是数组没有这个元素,所以不会被遍历到,而
undefined
则表示数组有这个元素,值是undefined
,所以遍历不会跳过。 - 如果一个对象的所有键名都是正整数或零,并且有
length
属性,那么这个对象就很像数组,语法上称为“类似数组的对象”(array-like object)。
var obj = {
0: "a",
1: "b",
2: "c",
length: 3,
};
1.1.3 in 运算符
- 检查某个键名是否存在,适用于对象,也适用于数组。
var arr = ["a", "b", "c"];
2 in arr; // true
"2" in arr; // true
4 in arr; // false
1.2 类似数组的对象
- 典型的“类似数组的对象”是函数的
arguments
对象,以及大多数 DOM 元素集,还有字符串。 - 数组的
slice
方法可以将“类似数组的对象”变成真正的数组。
var arr = Array.prototype.slice.call(arrayLike);
- 除了转为真正的数组,“类似数组的对象”还有一个办法可以使用数组的方法,就是通过
call()
把数组的方法放到对象上面。
function print(value, index) {
console.log(index + " : " + value);
}
Array.prototype.forEach.call(arrayLike, print);
1.3 数组遍历
1.3.1 for 循环
var a = [1, 2, 3];
for (var i = 0; i < a.length; i++) {
console.log(a[i]);
}
1.3.2 for…in 循环
- 注意:for…in 循环非常不建议用在数组上,for…in 是为遍历对象属性而构建的,当然数组也可以用。
- for…in 语句以任意顺序遍历一个对象的除 Symbol 以外的可枚举属性 。
var a = [1, 2, 3];
for (var i in a) {
console.log(a[i]);
}
1.3.3 while 循环
var a = [1, 2, 3];
// while循环
var i = 0;
while (i < a.length) {
console.log(a[i]);
i++;
}
// 逆向遍历,即从最后一个元素向第一个元素遍历
var l = a.length;
while (l--) {
console.log(a[l]);
}
1.3.4 for…of 循环
- for…of 语句在 可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句 。
- for of 循环是 ES6 的新增方法,针对 for in 循环的 bug,for of 循环就不会有问题:
const arr:any = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.name = 12;
for(const item of arr) {
console.log(item)
}
# 输出结果:
# 1 2 3 4 5 6 7 8 9
1.3.5 forEach 循环
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
forEach()
方法不返回值,只用来操作数据
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
arr.forEach((item, index, arr) => {
console.log(item)
});
# 输出结果:
# 1 2 3 4 5 6 7 8 9
1.3.6 map 循环
map 循环返回一个经过调用函数处理后的新的数组
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const res = arr.map((item,index,arr)=>{
return item + 1
})
console.log(res)
// [2, 3, 4, 5, 6, 7, 8, 9, 10]
- map 循环不会对空数组进行检测 。
- map 循环必须 return 。
- map 循环不会修改原数组。
- map 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。
- map 循环会针对每一项都进行循环,如果跳过则会返回 undefined,
1.3.7 filter 循环
filter() 循环返回一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const res = arr.filter((item,index,arr)=>{
return item > 3;
});
console.log(res)
// [4, 5, 6, 7, 8, 9]
- filter 循环不会对空数组进行检测。
- filter 循环不会改变原数组。
- filter 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。
1.3.8 some 循环
- some 循环查找数组中任意符合条件的元素并返回 boolean 值,当数组中有任意元素符合条件就返回 true 否则返回 fasle
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const res = arr.some((item,index,arr)=>{
return item > 3
})
console.log(res)
// true
- some 循环会依次执行数组的每一个元素。
- 如果有一个元素满足条件,则返回 true,且剩余的元素不会在执行检测 即 循环结束。
- some 循环不会对空数组进行检测
- some 循环不会改变原数组
- some 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。
1.3.9 every 循环
every 循环查找数组中所有符合条件的元素并返回 boolean 值,只有当数组中有所有元素都符合条件才返回 true 否则返回 fasle
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const res = arr.every((item,index,arr)=>{
return item > 3
})
console.log(res);
// false
- every 循环会检测数组的每一个元素
- 如果有一个元素不满足条件,则返回 false,且剩余元素不在检测 即 循环结束。
- every 循环不会对空数组进行检测
- every 循环不会改变原数组。
- every 循环接受三个参数,[第一参数]为数组中的每一项,[第二参数]为数组的下标,[第三个参数]为你要遍历的数组本身。第二和第三参数都是可选的。
1.3.10 reduce 循环
reduce() 循环接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const res = arr.reduce((total,item,index,arr)=>{
return total + item;
}, 0)
console.log(res);
// 45
- reduce 循环对于空数组是不会执行回调函数的。
- reduce 循环接受一个回调函数,和一个初始值。
- 回调函数接受四个参数:[第一参数]为数组中的每一项累加和,[第二参数]为数组的每一项,[第三个参数]为数组的下标,[第四个参数]为你要遍历的数组本身。第三和第四参数都是可选的。
- 初始值,即为指定第一次循环时,累加参数[total] 的值。
- 例如 demo 中,指定初始值为 0,则 reduce 循环的状态为:
[total + item]
0
0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
…
36 + 9 = 45
reduce 可以作为一个高阶函数,用于函数的 compose。
当然 reduce 的作用也不单单只作为一个累加器来用,我们还可以利用 reduce 的特性做其他的用途,比如数组的去重
1.4 扩展运算符
console.log(...[1, 2, 3])
// 1 2 3
-
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组。
-
修改原数组,会直接导致复制的数组的变化。
-
克隆数组:
const arr = [...arr1]
-
合并数组:
const arr = [...arr1, ...arr2]
注意是浅拷贝 -
拼接数组:
arr.push(...arr1)
-
代替 apply:
Math.max.apply(null, [x, y]) => Math.max(...[x, y])
-
转换字符串为数组:
[..."hello"]
-
转换类数组对象为数组:
[...Arguments, ...NodeList]
-
转换可遍历对象为数组:
[...String, ...Set, ...Map, ...Generator]
-
与数组解构赋值结合:
const [x, ...rest] = [1, 2, 3] // // x == 1 // rest == [2, 3]
-
计算 Unicode 字符长度:
Array.from("hello").length => [..."hello"].length
1.5 Array 对象
1.5.1 Array()
- 构造函数
var arr = new Array(2);
或var arr = Array(2);
Array()
作为构造函数,行为很不一致,不建议使用它生成新数组,最好直接使用数组字面量。
1.5.2 Array 静态方法
-
Array.isArray()
方法返回一个布尔值,表示参数是否为数组。它可以弥补typeof
运算符的不足。 -
Array.from()
:转换具有 Iterator 接口的数据结构为真正数组,返回新数组- 类数组对象:包含 length 的对象、Arguments 对象、NodeList 对象
- 可遍历对象:String、Set 结构、Map 结构、Generator 函数
-
Array.of()
:转换一组值为真正数组,返回新数组
1.5.3 Array 实例方法
1. 原数组
Array.prototype.valueOf()
所有对象都拥有的方法,表示对该对象求值。返回数组本身。Array.prototype.toString()
所有对象都拥有的方法,返回数组的字符串形式。
var arr = [1, 2, 3];
arr.toString() // "1,2,3"
var arr = [1, 2, 3, [4, 5, 6]];
arr.toString() // "1,2,3,4,5,6"
2. 修改原数组
-
Array.prototype.push()
数组末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。 -
Array.prototype.unshift()
数组第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组。 -
Array.prototype.shift()
删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组。 -
Array.prototype.pop()
删除数组的最后一个元素,并返回该元素。注意,该方法会改变原数组。push()
和pop()
结合使用,就构成了“后进先出”的栈结构(stack)。push()
和shift()
结合使用,就构成了“先进先出”的队列结构(queue)。
-
Array.prototype.splice()
删除原数组的一部分成员,并可以在删除的位置添加新的数组成员,返回值是被删除的元素。注意,该方法会改变原数组。 -
Array.prototype.sort()
对数组成员进行排序,默认是按照字典顺序排序。排序后,原数组将被改变。 -
Array.prototype.reverse()
颠倒排列数组元素,返回改变后的数组。注意,该方法将改变原数组。 -
Array.prototype.copyWithin()
:在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。会修改当前数组。 -
Array.prototype.fill()
:根据指定值填充整个数组,返回原数组
3. 返回新变量
-
Array.prototype.join()
以指定参数作为分隔符,将所有数组成员连接为一个字符串返回。如果不提供参数,默认用逗号分隔。 -
Array.prototype.concat()
多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变。 -
Array.prototype.slice()
提取目标数组的一部分,返回一个新数组,原数组不变。 -
Array.prototype.indexOf()
返回给定元素在数组中第一次出现的位置,如果没有出现则返回-1
-
Array.prototype.lastIndexOf()
返回给定元素在数组中最后一次出现的位置,如果没有出现则返回-1
-
Array.prototype.map()
将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。 -
Array.prototype.forEach()
也是对数组的所有成员依次执行参数函数。但是,forEach()
方法不返回值,只用来操作数据。- 这就是说,如果数组遍历的目的是为了得到返回值,那么使用
map()
方法,否则使用forEach()
方法。
- 这就是说,如果数组遍历的目的是为了得到返回值,那么使用
-
Array.prototype.filter()
用于过滤数组成员,满足条件的成员组成一个新数组返回。 -
Array.prototype.some()
接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值,表示判断数组成员是否符合某种条件- 只要一个成员的返回值是
true
,则整个some
方法的返回值就是true
,否则返回false
。
- 只要一个成员的返回值是
-
Array.prototype.every()
接受一个函数作为参数,所有数组成员依次执行该函数,返回一个布尔值,表示判断数组成员是否符合某种条件- 所有成员的返回值都是
true
,整个every
方法才返回true
,否则返回false
。
- 所有成员的返回值都是
-
Array.prototype.find()
:找出第一个符合条件的数组成员,返回该成员,如果没有符合条件的成员,则返回undefined
-
Array.prototype.findIndex()
:返回第一个符合条件的成员索引值 -
Array.prototype.keys()
:返回以索引值为遍历器的对象 -
Array.prototype.values()
:返回以属性值为遍历器的对象 -
Array.prototype.entries()
:返回以索引值和属性值为遍历器的对象- 数组空位:ES6 明确将数组空位转为 undefined(空位处理规不一,建议避免出现)
-
Array.prototype.reduce()
依次处理数组的每个成员,最终累计为一个值,从左到右处理 -
Array.prototype.reduceRight()
依次处理数组的每个成员,最终累计为一个值,从右到左- 累积变量。第一次执行时,默认为数组的第一个成员;以后每次执行时,都是上一轮的返回值。
- 当前变量。第一次执行时,默认为数组的第二个成员;以后每次执行时,都是下一个成员。
- 当前位置。一个整数,表示第二个参数(当前变量)的位置,默认为
1
。 - 原数组。
这四个参数之中,只有前两个是必须的,后两个则是可选的。
[1, 2, 3, 4, 5].reduce(function (
a, // 累积变量,必须
b, // 当前变量,必须
i, // 当前位置,可选
arr // 原数组,可选
) {
// ... ...
[1, 2, 3, 4, 5].reduce(function (a, b) {
console.log(a, b);
return a + b;
})
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15
1.6 应用
- 数组添加元素:
- 数组添加元素:
array1.push(x, y)
把元素 x 和 y 添加到 array1 中 - 合并数组:
array1.push(...array2)
把数组 array2 的元素依次添加到 array1 中
- 数组添加元素:
- 数组去重:
Array.from(new Set(array1))
对数组 array1 去重,返回一个新数组 - 数组过滤:
array1.filter((item) => item)
对数组 array1 过滤,返回一个新数组,保留非空的array1.filter((x) => { return x > 3 })
对数组 array1 过滤,返回一个新数组,保留 > 3 的
- 数组删除某些元素:
array1.splice(idx, 1);
删除数组下标为 idx 的元素 - 数组循环:
array1.forEach((item) => { xxxxxx })
对数组 array1 进行循环 - 对象数组取值:
array.map((item) => { return item.path })
取对象数组的某一值array.map((v) => { return {...v, xxx: y} })
取对象数组的某些值array.map((v) => {return { ...v, oe: (v.oe as string).replace(/\;/g, ',') };});
把对象数组的某个属性的值替换掉
- 数组包含某些元素:
array1.includes(item)
判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回 false。- 对象数组不能用 includes,可以使用 some 如何判断一个数组对象中是否存在某个对象
array1.some((i) => { return i.value === arg.value; })
有时 array1 的 length = 0 ,但是 array1 ? true : false; 仍为 true
空数组[]
和空对象{}
对应的布尔值,都是 true。所以有时不能只判断 array1 是否为空,还要判断 array1.length
看返回的是什么,有没有在 长度为 0 的时候就 return 掉if (result.total < 1) { return; }