为了不污染原生的 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 = 0while k < lenkValue = O[k]testResult = predicate(thisArg, kValue, k, O)->BooleantestResult is true, return kValueSet 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