call、apply、bind的实现

call实现

1. 给函数的原型中添加方法

Function.prototype.mycall = function() {
    console.log(123);
}

function num() {
    console.log('测试创建的函数是否包含mycall的方法');
}
function foo() {
    console.log('测试创建的函数是否包含mycall的方法');
}

num.mycall() //123
foo.mycall() //123

2. mycall函数中获取当前调用的方法,(Fn.mycall)调用的方法是隐式绑定,所以直接使用this就可以获取了

Function.prototype.mycall = function() {
    console.log(this); 
}
...
...
num.mycall() //[Function: num]
foo.mycall() //[Function: foo]

3.  此时函数已经拿到了后面只需要修改它的this指向就可以了,既然上面已经确定了是隐式绑定那只需要修改"."前面的参数就可以实现动态绑定this了。

Function.prototype.mycall = function(thisArg) {
    let fn = this
    thisArg.fn = fn;
    thisArg.fn();
}

function num() {
    console.log(this);
}
function foo() {
    console.log(this);
}

num.mycall({}) //{ fn: [Function: num] }
foo.mycall([123]) //[ 123, fn: [Function: foo] ]

4. 现在基本的this自定义绑定已经实现了,但是还有三个大的问题。

  1. thisArg.fn = fn;这段代码给this增加了fn函数(调用mycall的函数)。
  2. 当传入非对象类型无法绑定为this。
  3. 无法传人参数
Function.prototype.mycall = function(thisArg = window, ...args) { //获取自定义this及参数
    let fn = this

    thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg) : window; //对传人的this做对象转化,为null或者undefined改为window,
    thisArg.fn = fn;
    let result = thisArg.fn(...args); 

    delete thisArg.fn //删除fn
    return result //返回函数
}

function num() {
    console.log(this);
}
function foo() {
    console.log(this);
}

num.mycall({})
foo.mycall(123)

apply实现

Function.prototype.mycall = function (thisArg = window, args = []) { //获取自定义this及参数
    let fn = this

    thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg) : window; //对传人的this做对象转化,为null或者unified改为window,
    thisArg.fn = fn;

    if (!(args instanceof Array)) throw new SyntaxError("传入的参数类型不是数组"); //确保参数为数组类型
    let result = thisArg.fn(...args);

    delete thisArg.fn //删除fn
    return result //返回函数
}

function num() {
    console.log(this);
}
function foo(str) {
    console.log(this, str);
}

num.mycall({}, [])
foo.mycall('aaa', ['pxq'])

bind的实现

Function.prototype.mybind = function (thisArg = window, ...args) { //获取自定义this及参数
    let fn = this;
    thisArg = (thisArg !== null && thisArg !== undefined) ? Object(thisArg) : window;

    return function(...argsArray) {
        thisArg.fn = fn
        let result = thisArg.fn(...args, ...argsArray);

        delete thisArg.fn
        return result
    }
}

function num (num1, num2) {
    console.log(this, num1, num2);
}

function foo () {
    console.log(this);
}

var newNum = num.mybind({}, 10)
newNum(20)

var newFoo = foo.mybind([]);
newFoo() 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值