手写函数一:实现call,bind,apply函数

176 阅读1分钟
call,bind,apply都是改变this指向的方法。

区别:

  1. call传递参数序列
  2. apply传递参数数组
  3. bind也是传递参数序列,返回一个函数,需要再次调用

call函数

Function.prototype.myCall = function (context, ...args) {
    // 判断是否传递有效的context(this)
    context = (context === null || context === undefined) ? window : Object(context)
    // 判断是否传递有效的args
    args = args ? args : []
    // 给context传递独一无二的参 Symbol
    const key = Symbol()
    context[key] = this
    // 隐式绑定this
    const result = context[key](...args)
    // 删除key
    delete context[key]
    return result

}



function foo(params) {
    console.log('foo函数执行', this, this.key)
}
function sum(m, n) {
    console.log('sum函数执行', this)
    console.log(m + n)
}

foo.call('abc')
foo.myCall({ key: 41 })
foo.myCall('abc')
foo.myCall(undefined)
sum.myCall('abc', 1, 20)

apply函数

Function.prototype.myApply = function (context, argArray) {
    // 判断是否传递有效的context(this)
    context = (context === null || context === undefined) ? window : Object(context)
    // 给context传递独一无二的参 Symbol
    const key = Symbol()
    context[key] = this
    // 隐式绑定this
    let result
    if (argArray === undefined || argArray === null) {
        context[key]()
    } else if (Array.isArray(argArray)) {
        context[key](...argArray)
    } else {
        context[key](argArray)
    }

    // 删除key
    delete context[key]
    return result

}

function sum(m, n) {
    console.log('sum执行', this)
    console.log(m + n)
}

// sum.apply('abc', [10, 20])
sum.myApply('abc', [10, 20])
sum.myApply('abc', 10)

bind函数

Function.prototype.myBind = function (context, ...args) {
    // 判断是否传递有效的context(this)
    context = (context === null || context === undefined) ? window : Object(context)
    // 判断是否传递有效的args
    args = args ? args : []
    // 给context传递独一无二的参 Symbol
    const key = Symbol()
    context[key] = this
    return function (...argsNew) {
        // 隐式绑定this
        const result = context[key](...args, ...argsNew)
        // 删除key
        delete context[key]
        return result
    }
}

function sum(num1, num2, num3) {
    console.log(this)
    console.log(num1, num2, num3)
}
var result = sum.myBind('aaa', 10, 20,)
var a = result(40)
console.log(a)