为了不污染原生的 Array 对象, 实现通过 function 来实现

Eg:

// prototype
Array.prototype.find = function(predicate, /* thisArg*/) {}

// ours
function (collection, predicate) {}
1
2
3
4
5

# 解题思路 or 实现原理

find 方法对数组中的每一项元素执行一次 predicate 函数, 直至有一个 predicate 返回 true. 当找到了这样一个元素后, 该方法会立即返回这个元素的值, 否则返回 undefined. 注意predicate 函数会为数组中的每个索引调用即从 0 到 length - 1, 而不仅仅是那些被赋值的索引, 这意味着对于稀疏数组来说, 该方法的效率要低于那些只遍历有值的索引的方法.

  • 把传入的 this 转换成 Object对象, 需要null值处理 -> O

  • 取出 Objectlength -> 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

# 参考

Find MDN (opens new window)

TC39 Find (opens new window)