重写数组方法

forEach

  • 第一个参数:cb(value, index, array)
  • 第二个参数:指定回调中 this 指向
  • 回调中 this 指向默认为 window

原生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var arr = [
{
name: 'Lance',
age: 20,
},
{
name: 'GC',
age: 23
},
{
name: 'Shank',
age: 25
}
];

var obj = {
name: 'Lance',
age: 23
}

arr.forEach(function(value, index, arr) {
console.log(this); // 默认window
console.log(value, index, arr);
}, obj);

实现

1
2
3
4
5
6
7
8
9
Array.prototype.myForEach = function(cb) {
var _arr = this,
_len = _arr.length,
_caller = arguments[1] || window;

for (var i = 0; i < _len; i++) {
cb.call(_caller, _arr[i], i, _arr);
}
}

map

  • 和 forEach 类似,但是返回新数组
  • 如果数组成员是复杂类型(对象),那么在cb中修改item,会改变原数组;如果数组成员是基本类型,则不会修改原数组
  • map没实现深拷贝

原生

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
var arr = [
{
name: 'Lance',
age: 20,
},
{
name: 'GC',
age: 23
},
{
name: 'Shank',
age: 25
}
];

var obj = {
name: 'Lance',
age: 23
}

var newArr = arr.map(function(item, index, arr) {
item.name = this.name;
return item; // 必须返回,否则数组里边成员都是 undefined
}, obj);
console.log(newArr, arr);

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.myMap = function(cb) {
var _arr = this,
_len = _arr.length,
_caller = arguments[1] || window,
newArr = [];

for (var i = 0; i < _len; i++) {
// var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
newArr.push(cb.call(_caller, _arr[i], i, _arr));
}

return newArr;
}

filter

  • 返回新数组
  • 原数组成员是复杂类型,cb中修改也会影响原数组

原生

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
var arr = [
{
name: 'Lance',
age: 20,
},
{
name: 'GC',
age: 23
},
{
name: 'Shank',
age: 25
}
];

var obj = {
name: 'Lance',
age: 23
}

var newArr = arr.filter(function(item, index, arr) {
console.log(item, index, arr, this);
return item.age > 20;
}, obj);
console.log(newArr, arr);

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.myFilter = function(cb) {
var _arr = this,
_len = _arr.length,
_caller = arguments[1] || window,
newArr = [];

for (var i = 0; i < _len; i++) {
// var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
cb.call(_caller, _arr[i], i, _arr) && newArr.push(_arr[i]);
}

return newArr;
}

reduce

  • 返回一个“聚合”值
  • 没有第三个参数来指定cb中的this,始终为 window

原生

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
var arr = [
{
name: 'Lance',
age: 20,
},
{
name: 'GC',
age: 23
},
{
name: 'Shank',
age: 25
}
];

var obj = {
name: 'Lance',
age: 23
}

var newArr = arr.reduce(function(pre, item, index, arr) {
item.age >= 23 && pre.push(item);
return pre;
}, []);
console.log(newArr);

实现

1
2
3
4
5
6
7
8
9
10
11
12
Array.prototype.myReduce = function(cb, initialValue) {
var _arr = this,
_len = _arr.length,
_caller = window;

for(var i = 0; i < _len; i++) {
// var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
initialValue = cb.call(_caller, initialValue, _arr[i], i, _arr);
}

return initialValue;
};

reduceRight

  • 遍历顺序和 reduce 相反,是从后往前遍历

原生

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
var arr = [
{
name: 'Lance',
age: 20,
},
{
name: 'GC',
age: 23
},
{
name: 'Shank',
age: 25
}
];

var obj = {
name: 'Lance',
age: 23
}

var newArr = arr.reduceRight(function(pre, item, index, arr) {
item.age >= 23 && pre.push(item);
return pre;
}, []);
console.log(newArr);

实现

1
2
3
4
5
6
7
8
9
10
11
12
Array.prototype.myReduceRight = function(cb, initialValue) {
var _arr = this,
_len = _arr.length,
_caller = window;

for(var i = _len - 1; i >= 0; i--) {
// var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
initialValue = cb.call(_caller, initialValue, _arr[i], i, _arr);
}

return initialValue;
};

every

  • 返回 true or false

    • 所有 cb 结果都为 true 时,整体为 true
    • 只有有一个cb结果为 false,整体为 false

原生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var arr = [
{
name: 'Lance',
age: 20,
},
{
name: 'GC',
age: 23
},
{
name: 'Shank',
age: 25
}
];

var obj = {
name: 'Lance',
age: 23
}

var res = arr.every(function(item, index, arr) {
return item.age < 23;
}, obj);
console.log(res);

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.myEvery = function(cb) {
var _arr = this,
_len = _arr.length,
_caller = arguments[1] || window;

for (var i = 0; i < _len; i++) {
// var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
if (!cb.call(_caller, _arr[i], i, _arr)) {
return false;
}
}
return true;
};

some

  • 返回 true or false

    • 只有有一个cb结果为 true,整体就为 true;否则为 false

原生

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var arr = [
{
name: 'Lance',
age: 20,
},
{
name: 'GC',
age: 23
},
{
name: 'Shank',
age: 25
}
];

var obj = {
name: 'Lance',
age: 23
}

var res = arr.some(function(item, index, arr) {
return item.age <= 20;
}, obj);
console.log(res);

实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Array.prototype.mySome = function(cb) {
var _arr = this,
_len = _arr.length,
_caller = arguments[1] || window;

for (var i = 0; i < _len; i++) {
// var item = deepClone(_arr[i]); // 如果要实现深拷贝,可以加此行代码,同时把下边 _arr[i] 替换为 item
if (cb.call(_caller, _arr[i], i, _arr)) {
return true;
}
}

return false;
}