手写call()、apply()、bind()函数

先具备以下条件

了解call(),apply(),bind()的用法,这里不在多讲,可自行去MDN文查阅

了解this指向,以及es6扩展运算符,一点原型链知识

(以下函数其实都是用c++写的,我们用js模拟实现)

目录

一、call()

二、apply()

三、bind()


一、call()

this指向疑问:当前这个this指向谁?谁调用了就指向谁

如下面代码倒数第二行,foo调用了pm_call(),那么pm_call()这个函数里面当前的this就是foo

(不信?自行打印pm_call函数中的this)

// call
Function.prototype.pm_call = function (thisArg, ...args) {
    // 获取this
    let that = this
    // 如果一参传入的是string/number/null/undefined调用会报错
    // 所以对 这些边界进行处理,call方法对于null和undefined是会指向window
    if (thisArg == undefined || thisArg == null) {
        thisArg = window
    } else {
        thisArg = Object(thisArg)
    }
    // 绑定this
    thisArg.fn = that
    // 调用
    const res = thisArg.fn(...args)
    // 调用完后,删除这个方法
    delete thisArg.fn
    //如果有返回值
    console.log(`我是pm_call返回值(当前函数${this.name}): ${res}`)
    return res
}
// 测试代码
function foo() {
    console.log('foo', this)
}
function sum(num1, num2) {
    console.log('sum: ', num1 + num2, this, num1, num2)
    return num1 + num2
}
foo.pm_call({})//可以自行写123, '123', null, undefined测试
sum.pm_call({}, 20, 30)

二、apply()

call()已经写了注释了,这里不在重复注释

//apply
Function.prototype.pm_apply = function (thisArg, args) {
    let that = this
    if (thisArg == undefined || thisArg == null) {
        thisArg = window
    } else {
        thisArg = Object(thisArg)
    }
    //如果二参没传,就是undefined,...undefined就会报错
    args = args || []
    thisArg.fn = that
    const res = thisArg.fn(...args)
    delete thisArg.fn
    return res
}
// // 测试代码
function foo() {
    console.log('foo', this)
}
function sum(num1, num2) {
    console.log('sum: ', num1 + num2, this, num1, num2)
    return num1 + num2
}
foo.pm_apply({})
sum.pm_apply({}, [20, 30])

三、bind()

call()已经写了注释了,这里不在重复注释

//bind
Function.prototype.pm_bind = function (thisArg, ...args) {
    let that = this
    if (thisArg == undefined || thisArg == null) {
        thisArg = window
    } else {
        thisArg = Object(thisArg)
    }
    // 为什么要返回一个函数?bind本来返回就是一个拷贝原函数
    return function foo(...a) {
        thisArg.fn = that
        // 剩余参数合并
        const arr = [...args, ...a]
        const res = thisArg.fn(...arr)
        delete thisArg.fn
        return res
    }
}
// 测试代码
function sum(n1, n2, n3, n4) {
    console.log(`测试pm_bind函数:`, n1, n2, n3, n4)
}
const fun = sum.pm_bind({}, 10, 20)
fun(30, 40)

额外补充:call()和apply()的区别?

一参传的都一样,二参前者随便传,还可以接着传三参四参五参...,后者传数组

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值