/ JavaScript / 3924浏览

手写一个call、apply、bind

callapply接受一个上下文和剩余参数,apply一个数组接受剩余参数,call则以逗号分割接受剩余参数。

let o1 = { name: 'o1' }
let o2 = {
    name: 'o1' ,
    fn() { console.log(this.name, arguments) }
}
o2.fn() // o2
o2.fn.apply(o1, [1, 2, 3]) // o1 [1,2,3]
o2.fn.call(o1, 1, 2, 3) // o1 [1,2,3]

定义自己的apply、call、bind方法

Function.prototype.applyFn = function () { }
Function.prototype.callFn = function () { }
Function.prototype.bindFn = function () { }

改变上下文this指向

我们知道this最终会指向调用这个方法的对象。关于this>
举个🌰:

let name = 'window'
let o1 = { name: 'o1' }
let o2 = {
    name: 'o1' ,
    fn() { console.log(this.name, arguments) }
}
o2.fn() // o2
let fn = o2.fn // 定义在全局作用域下的变量都会被挂在window对象下
fn() // window 等价于 window.fn()

我们就可以利用这种特性,先将函数本身暂时挂在context下,再通过context.__fn调用。

Function.prototype.applyFn = function () {
    let args = Array.isArray(arguments[1]) ? arguments[1] : [],
        context = arguments[0] || window
    context.__fn = this
    context.__fn(...args)
    delete context.__fn
}
Function.prototype.callFn = function () {
    let args = [], context = arguments[0] || window
    for (let i = 1, arg; arg = arguments[i++];) {
        args.push(arg)
    }
    context.__fn = this
    context.__fn(...args)
    delete context.__fn
}

bind

bind返回一个上下文经过绑定的函数。bind首先会接受一个上下文,然后返回的函数再负责接受剩余参数。

Function.prototype.bindFn = function () {
    // 首先接受上下文
    let context = arguments[0] || window
    let that = this // 保存当前函数
    return function () {
        // 然后返回的函数接受剩余参数
        let args = []
        for (let i = 0, arg; arg = arguments[i++];) {
            args.push(arg)
        }
        that.callFn(context, ...args)
    }
}
更新于
JavaScript中的this到底指向谁?
JavaScript中的this到底指向谁?
手写一个Promise
手写一个Promise
防抖(debounce)、节流(throttle)原理与实现
防抖(debounce)、节流(throttle)原理与实现
JS如何等待多个异步操作完成后再进行操作
JS如何等待多个异步操作完成后再进行操作
原型
原型

0

  1. This post has no comment yet

发表回复