# 手写代码

# debounce 防抖

function debounce(fn, delay = 500) {
    let timer = null;

    return function() {
        if (timer) {
            clearTimeout(timer);
            timer = null;
        }

        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, delay);
    };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# throttle 节流

function throttle(fn, delay = 500) {
    let timer = null;

    return function() {
        if (timer) {
            return;
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments);
            timer = null;
        }, delay);
    };
}
1
2
3
4
5
6
7
8
9
10
11
12
13

# cloneDeep 深拷贝

function cloneDeep(arg) {
    //不是数组,或者是 null || undefined
    if (typeof arg !== "object" || arg == null) {
        return arg;
    }

    let res;
    if (arg instanceof Array) {
        res = [];
    } else {
        res = {};
    }

    for (let key in arg) {
        if (arg.hasOwnProperty(key)) {
            res[key] = cloneDeep(arg[key]);
        }
    }
    return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# isEqual 深度比较

function isObject(obj) {
    return typeof obj === "object" && obj !== null;
}
function isEqual(obj1, obj2) {
    if (!isObject(obj1) || !isObject(obj2)) {
        return obj1 === obj2;
    }
    if (obj1 === obj2) {
        return true;
    }

    const obj1Keys = Object.keys(obj1);
    const obj2Keys = Object.keys(obj2);

    if (obj1Keys.length !== obj2Keys.length) {
        return false;
    }

    for (let key in obj1) {
        let res = isEqual(obj1[key], obj2[key]);
        if (!res) {
            return false;
        }
    }
    return true;
}
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

# new

function myNew(fn, ...arg) {
    let obj = Object.create(fn.prototype);
    let res = fn.apply(obj, arg);
    return res instanceof Object ? res : obj;
}
1
2
3
4
5

# call

Function.prototype.call = function(_this, ...arg) {
    let __this = _this ? _this : Object(_this);
    const fnKey = new Symbol("fnKey");
    __this[fnKey] = this;
    const res = __this[fnKey](...arg);
    delete __this[fnKey];
    return res;
};
1
2
3
4
5
6
7
8

# bind

Function prototype.bind = function (_this,...arg){
    let fn = this;
    return function (...arg2){
        return fn.apply(_this,[...arg,...arg2])
    }
}
1
2
3
4
5
6

# curry(函数柯里化)

function curry(fn, ...arg) {
    let length = fn.length;
    return function(...arg2) {
        let newArg = [...arg, ...arg2];
        if (newArg.length < length) {
            return curry.call(this, fn, ...newArg);
        } else {
            return fn.call(this, ...newArg);
        }
    };
}
1
2
3
4
5
6
7
8
9
10
11

# instanceof

  • instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。
  • instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性。
  • 不能检测基本数据类型,在原型链上的结果未必准确,不能检测 null,undefined
  • 实现:遍历左边变量的原型链,直到找到右边变量的 prototype,如果没有找到,返回 false
function myInstanceOf(a, b) {
    let left = a.__proto__;
    let right = b.prototype;
    while (true) {
        if (left == null) {
            return false;
        }
        if (left == right) {
            return true;
        }
        left = left.__proto__;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13