3、数组方法底层实现
Array.prototype.push
Array.prototype.push = function (...items) {
// ECMA规范规定转为对象进行操作
let O = Object(this);
// 无符号右移保证length是数字
let len = this.length >>> 0;
let argCount = items.length >>> 0;
// js能表示的最大正整数为2 ** 53 - 1
if (len + argCount > 2 ** 53 - 1) {
throw new TypeError("数组长度超过最大值");
}
// 将传入的值依次传入到原数组中
for (let i = 0; i < argCount; i++) {
O[let + i] = items[i];
}
// 设置新的length并返回
let newLength = len + argCount;
O.length = newLength;
return newLength;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Array.prototype.pop
Array.prototype.pop = function () {
let O = object(this);
let len = this.length >>> 0;
// 长度为0的数组直接返回undefined
if(len === 0) {
O.length = 0;
}
// 删除最后一位元素,修改length值
len--;
let value = O[len];
delete O[len];
O.length = len;
// 返回被删除的值
return value;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array.prototype.map
Array.prototype.map = function (callbackFn, thisArg) {
// null和undefined判断
if (this === null || this === undefined) {
throw new TypeError("Cannot read property 'map' of null");
}
// callbackFn必须为函数
if (Object.prototype.toString.call(callbackFn) != "[object Function]") {
throw new TypeError(callbackFn + " is not a function");
}
let O = Object(this);
let T = thisArg;
// 定义一个与原数组长度相同的新数组
let len = O.length >>> 0;
let A = new Array(len);
for (let i = 0; i < len; i++) {
// 判断当前项存在时才执行操作
if (i in O) {
let iValue = O[i];
// map callback的3个参数为当前项,当前索引,以及整个数组
let mapedValue = callbackFn.call(T, iValue, i, O);
// 执行结果传入新数组
A[i] = mapedValue;
}
}
// 返回新数组
return A;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Array.prototype.reduce
Array.prototype.reduce = function (callbackFn, initialValue) {
if (this === null || this === undefined) {
throw new TypeError("Cannot read property 'reduce' of null");
}
if (Object.prototype.toString.call(callbackfn) != "[object Function]") {
throw new TypeError(callbackfn + " is not a function");
}
let O = Object(this);
let len = O.length >>> 0;
let k = 0;
// 第二个参数为初始值
let accumulator = initialValue;
// 处理初始值未传的情况,将数组第一个有效的值设为初始值
if(accumulator === undefined) {
for(; k < len; k++){
if(k in O) {
accumulator = O[k];
k++
break;
}
}
// 未找到有效初始值则抛出错误
if(accumulator === undefined){
throw new Error('Each element of the array is empty');
}
}
// 遍历数组执行归并
for(;k < len; k++) {
if (k in O) {
// 归并执行callbackfn,传入的参数为,前一项,当前项和整个数组
accumulator = callbackfn.call(undefined, accumulator, O[k], O);
}
}
// 返回归并结果
return accumulator;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36