Appearance
arrayApi
数组常用API
属性 | 说明 |
---|---|
map | 遍历数组,不影响原数组 |
filter | 过滤,不影响原数组 |
concat | 遍历数组,不影响原数组 |
push/pop | 末尾 推入和末尾弹出,影响原数组 |
unshift/shift | 头部 推入和头部弹出,影响原数组 |
sort | 排序与反转,影响原数组 |
slice | 返回截断后的新数组,不影响原数组 |
splice | 返回删除元素组成的数组,value 为插入项,影响原数组 |
join | 将数组 转换成字符串 ,不影响原数组 |
split | 字符串 将数组转换成数组 ,不影响原数组 |
forEach | 无法 break,可以用 try/catch中 thrownewError来停止 |
some | 有一项返回 true,则整体为 true |
every | 有一项返回 false,则整体为 false |
indexOf/lastIndexOf | 查找数组项,返回对应的下标 |
reduce/reduceRight | 两两执行,prev 为上次化简函数的 return值,cur 为当前值(从第二项开始) |
slice、splice
- slice 返回截断后的新数组,
不影响原数组
- splice 返回删除元素组成的数组,value 为插入项,
影响原数组
join、split
- join 将
数组
转换成字符串
,不影响原数组
- split
字符串
将数组转换成数组
,不影响原数组
数组、对象不会自动加分号,会拼接上去
js
let a = [1, 2, 3]
[2] // => [1,2,3][2]
console.log(a); // 3
let b = { x: 10 }
["x"]; // => {'x':10}['x']
console.log(b); // 10
indexOf,includes 区别?
- indexOf 返回的是数值类型,并且 indexOf 不能查找 NaN
- includes 返回的布尔类型,includes 可以查询 NaN
js
let arr = [1, 2, NaN];
console.log(arr.indexOf(NaN)); // -1
console.log(arr.includes(NaN)); // true
类数组的特征,需要有 length、push 属性
js
let arrayLike = {
0: "a",
1: "b",
4: "4",
length: 2,
push: Array.prototype.push,
};
console.log(arrayLike.length); // 2
console.log(arrayLike[0]); // a
console.log(arrayLike[1]); // b
console.log(arrayLike[2]); // undefined length到2就结束
arrayLike.push(100); // 只有调用push 操作会修改长度(push源码解析)
console.log(arrayLike.length); // 3
console.log(arrayLike[2]);
// 数组push源码,存储索引的值,长度+1
function push(val) {
this[this.length] = val;
this.length = ++this.length;
}
// 类数组转数组
console.log(Array.from(arrayLike));
数组长度问题
js
const arr1 = [1];
const arr2 = [1, ,];
const arr3 = new Array("10"); // 创建长度为1的数组,元素的值是10
const arr4 = new Array(10); // 创建长度为10的数组,10个元素都是empty
console.log(arr1.length, arr1); // 1 [1]
console.log(arr2.length, arr2); // 2 (2) [1, 空白]
console.log(arr3.length, arr3); // 1 ['10']
console.log(arr4.length, arr4); // 10 [空属性 × 10]
数组空元素 empty,在 map、forEach...,遍历时会跳过
js
function createData() {
return new Array(1000).map((v, i) => () => {
return { name: `name${i + 1}` };
});
}
const data = createData();
console.log(data); // [empty × 1000]
数组 entries 实现
js
// entries next
Array.prototype.entries = function () {
const O = Object(this);
let index = 0;
const len = O.length;
function next() {
if (index < len) {
return { value: [index, O[index++]], done: false };
}
return { value: undefined, done: true };
}
return {
next,
// 可迭代
[Symbol.iterator]: function () {
return {
next,
};
},
};
};
let arr = [1, 2, 3];
let n = arr.entries();
console.log(n.next());
console.log(n.next());
console.log(n.next());
console.log(n.next());
for (let [k, v] of arr.entries()) {
console.log(`k:${k}`, `v:${v}`);
}
数组 includes 实现
js
function ToIntegerOrInfinity(argument) {
var num = Number(argument);
// + 0 和 -0
if (Number.isNaN(num) || num == 0) {
return 0;
}
if (num === Infinity || num == -Infinity) {
return num;
}
var inter = Math.floor(Math.abs(num));
if (num < 0) {
inter = -inter;
}
return inter;
}
Array.prototype.includes = function (item, fromIndex) {
// call, apply调用,严格模式
if (this == null) {
throw new TypeError("无效的this");
}
var O = Object(this);
var len = O.length >> 0;
if (len <= 0) {
return false;
}
var n = ToIntegerOrInfinity(fromIndex);
if (fromIndex === undefined) {
n = 0;
}
if (n === +Infinity) {
return false;
}
if (n === -Infinity) {
n = 0;
}
var k = n >= 0 ? n : len + n;
if (k < 0) {
k = 0;
}
const isNAN = Number.isNaN(item);
for (let i = k; i < len; i++) {
if (O[i] === item) {
return true;
} else if (isNAN && Number.isNaN(O[i])) {
return true;
}
}
return false;
};
const arr = ["a", "b", "c"];
console.log("arr include -100->0:", arr.includes("c", -100));
console.log("arr include -100->0:", arr.includes("a", -1));
console.log("arr include 1:", arr.includes("a", -Infinity));
console.log("arr include 1:", arr.includes("a", Infinity));
数组扁平化
js
const nums = [1, 2, [3, 4, [100, 200], 5], 6]
// 数组元素是 {x: 100} 等引用类型,就不可以了
nums.toString() // '1,2,3,4,100,200,5,6'
// 正无穷
nums.flat(Infinity) // [1, 2, 3, 4, 100, 200, 5, 6]
// 递归
function flatten(arr=[],newArr=[]){
arr.forEach((_)=>{
if(Array.isArray(_)){
flatten(_,newArr)
}else{
newArr.push(_)
}
})
return newArr;
}
console.log(flatten(nums))