手写实现call、apply、bind方法

1、call

1)实现代码

call 方法是在Function的原型对象上的方法, 所以所有的函数都可调用。我们手写的方法也放在Function的原型对象上。

Function.prototype.myCall = function (context, ...args) {
        // 创建一个变量保存需要修改的this指向的对象, 如果没有传入就让this指向 window
        let newThis = context || window;
        // 给这个对象添加一个 fun 方法,这里的 this 就是调用 myCall 的这个函数
        newThis.fun = this;
        // 执行这个对象的 fun 方法, 并将 myCall 中传入的后续参数传给它;将执行结果保存给变量 res
        let res = newThis.fun(...args);
        // 删除这个对象的 fun 方法 避免产生副作用
        delete newThis.fun
        // 将执行结果返回
        return res
    }

2)效果验证

let obj = {
        name: "xiaoming",
        age: 24,
        sayHello: function (job, hobby) {
            console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}`);
        }
    }
    let obj1 = {
        name: "lihua",
        age: 30
    }
    obj.sayHello.myCall(obj1, '设计师', '画画'); // 我叫lihua,今年30岁。我的工作是: 设计师,我的爱好是: 画画。


2、apply

1)实现代码

apply 的实现基本和call相同, 区别在于接参方式不同

Function.prototype.myApply = function (context, args) {
        // 创建一个变量保存需要修改的this指向的对象, 如果没有传入就让this指向 window
        let newThis = context || window;
        // 给这个对象添加一个 fun 方法,这里的 this 就是调用 myApply 的这个函数
        newThis.fun = this;
        // 执行这个对象的 fun 方法, 并将 myApply 中传入的第二个参数展开传给它;将执行结果保存给变量 res
        let res = newThis.fun(...args);
        // 删除这个对象的 fun 方法 避免产生副作用
        delete newThis.fun
        // 将执行结果返回
        return res
    }

2)效果验证

let obj = {
        name: "xiaoming",
        age: 24,
        sayHello: function (job, hobby) {
            console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}`);
        }
    }
    let obj1 = {
        name: "lihua",
        age: 30
    }
    obj.sayHello.myApply(obj1, ['设计师', '画画']); // 我叫lihua,今年30岁。我的工作是: 设计师,我的爱好是: 画画。

3、bind

1)实现代码

bind的里面会返回一个修改了this指向的function,在调用这个function时会把bind中传入的参数和调用函数时的传入的参数拼接一起传入给它

Function.prototype.myBind = function (context, ...args) {
        // 创建一个变量保存需要修改的this指向的对象, 如果没有传入就让this指向 window
        let newThis = context || window;
        // 给这个对象添加一个 fun 方法,这里的 this 就是调用 myBind 的这个函数
        newThis.fun = this;
        // 返回一个函数
        return function (...someArgs) {
            // 执行这个对象的 fun 方法, 并将 myBind 中传入的后续参数拼接调用时传入的参数一起传给它;将执行结果保存给变量 res
            let res = newThis.fun(...args, ...someArgs);
            // 删除这个对象的 fun 方法 避免产生副作用
            delete newThis.fun
            // 将执行结果返回
            return res
        }    
    }

2)效果验证

let obj = {
        name: "xiaoming",
        age: 24,
        sayHello: function (job, hobby) {
            console.log(`我叫${this.name},今年${this.age}岁。我的工作是: ${job},我的爱好是: ${hobby}`);
        }
    }
    let obj1 = {
        name: "lihua",
        age: 30
    }

    obj.sayHello.myBind(obj1, '设计师', '画画')(); // 我叫lihua,今年30岁。我的工作是: 设计师,我的爱好是: 画画。
    obj.sayHello.myBind(obj1, '设计师')('画画'); // 我叫lihua,今年30岁。我的工作是: 设计师,我的爱好是: 画画。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慢步者_rambler

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值