为了不污染原生的 Array 对象, 实现通过 function 来实现
Eg:
// prototype
Array.prototype.find = function(predicate, /* thisArg*/) {}
// ours
function (collection, predicate) {}
1
2
3
4
5
2
3
4
5
# 解题思路 or 实现原理
find
方法对数组中的每一项元素执行一次 predicate
函数, 直至有一个 predicate
返回 true
. 当找到了这样一个元素后, 该方法会立即返回这个元素的值, 否则返回 undefined
. 注意predicate
函数会为数组中的每个索引调用即从 0 到 length - 1
, 而不仅仅是那些被赋值的索引, 这意味着对于稀疏数组来说, 该方法的效率要低于那些只遍历有值的索引的方法.
把传入的
this
转换成Object
对象, 需要null
值处理 ->O
取出
Object
的length
->len
判断传入
predicate
的是否是function
, 抛出异常TypeError exception
设置计数器
k = 0
while k < len
kValue = O[k]
testResult = predicate(thisArg, kValue, k, O)
->Boolean
testResult is true, return kValue
Set k to k + 1
Return undefined
# 参数
predicate
在数组每一项上执行的函数, 接收 3 个参数:
element
当前遍历到的元素
index
可选当前遍历到的索引
array
可选数组本身
thisArg
可选执行回调时用作
this
的对象
# 返回值
返回数组中满足提供的测试函数的第一个元素的值. 否则返回 undefined
# 实现代码
/*
* @Author: Rainy
* @Date: 2019-11-14 19:25:01
* @LastEditors : Rainy
* @LastEditTime : 2020-02-05 15:58:15
*/
import { _isArray } from '../isArray';
import { ArrayMap, WithParamsFunction } from 'types';
// ours
export function _find(collection: ArrayMap<any>, predicate: WithParamsFunction): any {
if (!_isArray(collection)) {
throw new Error('The first parma must be a Array');
}
for(const index in collection) {
if (predicate(collection[index], index, collection)) {
return collection[index];
}
}
return null;
}
// @ts-ignore
// prototype
Array.prototype._find = function(callback: WithParamsFunction/*, thisArg*/) {
if (this == null) {
throw new TypeError('null or undefined');
}
if (typeof callback !== 'function') {
throw new TypeError('callback is not a function');
}
const oldArr = Object(this);
const len = oldArr.length >>> 0;
const thisArg = arguments.length >= 2 ? arguments[1] : void 0;
let k = 0;
while(k++ < len) {
if(k in oldArr) {
const val = oldArr[k];
if(callback.call(thisArg, val, k, oldArr)) {
return val;
}
}
}
return void 0;
}
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
37
38
39
40
41
42
43
44
45
46
47
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
37
38
39
40
41
42
43
44
45
46
47