call、apply、bind应用及实现原理

228 阅读1分钟
  • call、apply、bind通常用来改变函数或者对象的this指向,不同之处是call和apply返回的是this改变之后的执行结果,而bind返回的是一个函数,call接收n个参数,第一个目标对象,后面的可以是调用call函数的参数,apply和call除了参数之外其它基本一样,apply接收两个参数,第二个是一个数组,bind和call的区别就是bind返回的是一个函数

  • apply实现

    Object.prototype.myApply = function (fn) {
    // fn为undefined或者null时,根据条件将其设为global或者window
    if(!fn){
    fn = typeof window === "undefined" ? global : window
    }
    let result
    let args = [...arguments[1]]
    fn.x = this if(!args){
    result = fn.x()
    }else{
    result = fn.x(...args)
    }
    return result
    }

  • call实现原理

    Object.prototype.myCall = function (fn) {
    // fn为undefined或者null时,根据条件将其设为global或者window
    if(!fn) {
    fn = typeof window === "undefined" ? global : window
    }
    let result
    let args = [...arguments].slice(1)
    fn.x = this if(!args){
    result = fn.x()
    }else{
    result = fn.x(...args)
    }
    return result
    }

  • bind实现原理

    Object.prototype.myBind = function(fn) {
    if(!fn){
    fn = typeof window === "undefined" ? global : window
    }
    let arges = [...arguments].slice(1)
    // 提前拿到this,防止this改变
    let that = this
    const F = function (){
    let args = [...arguments]
    if(this instansceof F) { //考虑new F的情况
    return that.call(this,...arges,...args )
    }
    return that.call(fn,...arges,...args )
    }
    // 维护原型 if(this.prototype) {
    F.prototype = this.prototype
    }
    return F
    }

  • 测试用例

    const a = {
    name: "jake",
    age: 15,
    skill: ["swimming","basketball"]
    }
    name = "hello"
    function b(a,b){
    let name = "mike"
    console.log(a,b)
    return this.name
    }
    function B(name,age){
    this.name = name
    this.age = age
    }
    B.prototype.show = function(){
    console.log(this.name, this.age)
    }
    let c = B.myBind(null, "mini")
    let d = new c(19)
    d.show()//mini 19
    console.log(d)//B { name: 'mini', age: 19 }

  • 个人觉得,其实bind方法有点像柯里化,同样可以达到延迟函数执行以及保存公用变量的功能,在实现bind的时候因为返回的是一个函数,所以可以使用new操作符强行改变this,在实现的时候需要注意,还有就是要记得维护调用函数的原型