手写简单的apply、call和bind

218 阅读2分钟

一、手写call

  • 先来看下call的使用

    let obj = { name: 'obj' } var name = 'window' function f(lastname) { console.log(this.name + ' ' + lastname) } f.call(obj, 'sun')

    // 输出obj sun

  • 思考:能直接通过函数.调用,通过我们学到的原型链的知识,我们可以将callFun写到prototype上

    Function.prototype.callFun = function(obj, ...args) {

    }

  • 思考:现在关键的部分是怎么能让callFun中执行function f中的代码,然后让this优先寻找obj中的值,那么还是结合之前学的原型链的知识,将方法f赋给obj的原型,然后执行obj原型的这个方法,这样this优先寻找obj的属性,找不到才会像上一级找

    Function.prototype.callFun = function(obj, ...args) { obj.proto._fn = this let result = obj._fn(args) delete obj.proto._fn return result }

  • 测试

    f.callFun(obj, 'sun') // obj sun

二、手写apply

  • 先来看下apply的使用

    let obj = { name: 'obj' } var name = 'window' function f(lastname) { console.log(this.name + ' ' + lastname) } f.apply(obj, ['dong'])

    // 输出obj dong

  • 思考:能直接通过函数.调用,通过我们学到的原型链的知识,我们可以将applyFun写到prototype上

    Function.prototype.applyFun = function(obj, args) {

    }

  • 思考:理解了call的写法就能很快反应到apply的写法,只需要理解ES6的结构赋值即可

    Function.prototype.applyFun = function(obj, args) { obj.proto._fn = this let result = obj._fn(args) delete obj.proto._fn return result }

  • 测试

    f.applyFun(obj, ['dong']) // obj dong

三、手写bind

  • 先来看下bind的使用

    let obj = { name: 'obj' } var name = 'window' function f(lastname) { console.log(this.name + ' ' + lastname) } f.bind(obj, 'mei')()

    // 输出obj mei

  • 思考:看到上面调用的方式我们就可以指定bind返回的一定一个函数

    Function.prototype.bindFun = function(obj, ...args) { let result = function () {

    } return result }

  • 思考:函数中执行的一定也是函数f的方法,那我们可以模仿call和apply

    Function.prototype.bindFun = function(obj, ...args) { obj.proto._fn = this let result = function () { return obj._fn(args) } return result }

  • 测试

    f.bindFun(obj, 'mei')() // obj mei

四、上面的写法只是想表达一个思想,有很多没有考虑在内,希望理解有误可以指出一起学习