# 基础手写

# 1. 手写一个new

function _new(fn, ...args) {
    let obj = Object.create(fn.prototype);
    let res = fn.apply(this, args);
    return typeof res === 'object' ? res : obj;
}
1
2
3
4
5

# 2. 实现call

  1. 判断当前this是否为函数,防止Function.prototype.myCall() 直接调用
  2. context 为可选参数,如果不传的话默认上下文为 window
  3. context 创建一个 Symbol(保证不会重名)属性,将当前函数赋值给这个属性
  4. 处理参数,传入第一个参数后的其余参数
  5. 调用函数后即删除该Symbol属性
Function.prototype.myCall = function (context = window, ...args) {
    //防止Function.prototype.myCall()直接调用
    if (this === Function.prototype) {
        return undefined;
    }
    context = context || window;
    let fn = Symbol();
    context[fn] = this;
    let result = context[fn](...args);
    delete context[fn];
    return result;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 3. 实现apply

apply实现类似call,参数为数组

Function.prototype.myApply = function (context = window, args) {
    if(this === Function.prototype){
        return undefined;
    }
    context = context || window;
    let fn = Symbol();
    context[fn] = this;
    let res;
    if(Array.isArray(args)){
       res = context[fn](...args);
    }else{
        res = context[fn]();
    }
    delete context[fn];
    return res;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 4.实现bind

  1. 返回一个函数
  2. 可以传入参数
  3. 返回的函数可以做构造函数
Function.prototype.myBind = function (context, ...args) {
    //错误处理
    if (typeof this !== 'function') {
        throw new Error('Function.prototype.myBind must be a function');
    }
    let self = this;
    function fNop(){};
    //返回函数且传参
    function fBound(...args2) {
        self.apply(this instanceof self ? this : context, args.concat(args2));
    }
    //构造函数效果
    fNop.prototype = self.prototype;
    fBound.prototype = new fNop();
    return fBound;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

#

Last Updated: 10/29/2020, 1:21:25 AM