手写js中call、apply、bind函数

手写call

原理

将需要改变this指向的函数暂时性的设置为需要设置this指向的对象的函数。

代码

// 定义mycall方法,所有函数对象都是Function对象
Function.prototype.mycall = function (thisArg, ...args) {
    // 设置this,此时this指向原函数,之后将指向thisArg
    thisArg.f = this
    // 接收剩余参数并得到结果
    const res = thisArg.f(...args)
    // 移除函数
    delete thisArg.f
    // 返回结果
    return res
}

// 测试样例
const person = {
    name: '南辞w'
}
function func(numA, numB) {
    console.log(this)
    console.log(numA, numB)
    return numA + numB
}
const res = func.mycall(person, 2, 8)
console.log('返回值为', res)

调优

对象中可能会出现函数重名冲突,可以利用Symbol()进行处理

调优后代码

Function.prototype.mycall = function (thisArg, ...args) {
    const key = Symbol('key')
    thisArg[key] = this
    const res = thisArg[key](...args)
    delete thisArg[key]
    return res
}

const person = {
    name: '南辞w'
}
function func(numA, numB) {
    console.log(this)
    console.log(numA, numB)
    return numA + numB
}
const res = func.mycall(person, 2, 8)
console.log('返回值为', res)

手写apply

原理

改变this的方法同上,但接收的参数为数组形式,可以之间用 '...' 来展开接收

代码

Function.prototype.myapply = function (thisArg, args) {
    const key = Symbol('key')
    thisArg[key] = this
    const res = thisArg[key](...args)
    delete thisArg[key]
    return res
}

const person = {
    name: '南辞w'
}

function func(numA, numB, numC) {
    console.log(this)
    console.log(numA, numB, numC)
    return numA + numB + numC
}

const res = func.myapply(person, [2, 8, 10])
console.log('返回值为', res)

手写bind

原理

改变this指向同上,但是此函数返回的是新的函数,并且可以分批次传值,前后次序不要弄混了

代码

Function.prototype.mybind = function (thisArg, ...args) {
    return (...reArgs) => {
        return this.call(thisArg, ...args, ...reArgs)
    }
}

const person = {
    name: '南辞w'
}
function func(numA, numB, numC, numD) {
    console.log(this)
    console.log(numA, numB, numC, numD)
    return numA + numB + numC + numD
}
const bindFunc = func.mybind(person, 1, 2)
const res = bindFunc(3, 4)
console.log('返回值为', res)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值