手写call、apply、bind函数

来源

https://juejin.cn/post/6968713283884974088#heading-9
https://mp.weixin.qq.com/s/uKPVedfQkgEPYoRUtwyeQQ

call

Function.prototype.mCall = function (context, ...args) {
    context = context || window || global;

    // 避免变量名重复
    const funcName = Symbol();
    // 保证函数执行时的this是context(谁调用的该函数,谁就是函数执行时的this)
    context[funcName] = this;
    const res = args.length ? context[funcName](...args) : context[funcName]();
    // 对应上面的添加,避免对context造成变量污染
    delete context[funcName];
    return res;
}

apply

Function.prototype.mApply = function (context, args = []) {
    context = context || window || global;

    const funcName = Symbol();
    context[funcName] = this;

    // 传入的参数不是数组
    if (!Array.isArray(args)) {
        args = [];
    }

    const res = args.length ? context[funcName](...args) : context[funcName]();
    delete context[funcName];
    return res;
}

bind

这里有一些特殊,如果绑定后返回的新函数被使用new运算符调用,绑定时的this参数会被忽略

参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
image

原bind函数关于new操作符的使用

参考:
https://www.webhek.com/post/javascript-bind.html
https://mp.weixin.qq.com/s/nI8VHuVQP73DGBrBdh5i2w

function Person (name, age) {
    this.name = name;
    this.age = age;
    console.log(this);
}
const mPerson = Person.bind({ height: 180 });
mPerson('zhangsan', 18); // { height: 180, name: 'zhangsan', age: 18 }
new mPerson('lisi', 19); // Person { name: 'lisi', age: 19 } ,绑定时的this被忽略

手写实现

Function.prototype.mBind = function (thisArg, ...args) {
    thisArg = thisArg || window || global;
    const fn = this;
    // 返回命名函数,用于比较是否是使用new运算符调用的绑定函数
    return function /*newFn*/(...newArgs) {
        // 是使用new运算符调用的该函数,忽略thisArg
        // if (this instanceof newFn) {
            // return new fn(...args, ...newArgs);
        // }
        // 或者下面这样。`new.target`可以检测函数是否是用`new`运算符调用的
        if (new.target) {
            return new fn(...args, ...newArgs)
        }
        return fn.apply(thisArg, [...args, ...newArgs]);
    }
}
posted @ 2021-11-30 13:39  酉云良  阅读(70)  评论(0)    收藏  举报