手写call、apply、bind详解

个人博客网站欢迎交流:萤火之森:https://blog.xkongkeji.com

手写call、apply、bind

三者都是改变函数执行时的上下文,也就是就是改变this的指向。

call(obj,arg1,arg2) //call()的参数一个一个的传

函数.call(第一个参数:想让函数中this指向谁,就传谁进来,
后面的参数:本身函数需要传递实参,需要几个实参,就一个一个的传递即可);
call的作用: 1. 调用函数 2.指定函数中this指向

apply(obj,[arg1,arg2] //apply()的第二个参数则是一个数组

函数.apply(第一个参数:想让函数中this指向谁,就传谁进来,
第二个参数:要求传入一个数组,数组中包含了函数需要的实参)
apply的作用: 1. 调用函数 2, 指定函数中this的指向

bind(this) // bind()返回的其实是一个函数,并不会立即执行。

函数.bind(第一个参数:想让函数中this指向谁,就传谁进来,
后面的参数:本身函数需要传递实参,需要几个实参,就一个一个的传递即可)
bind的作用: 1. 克隆当前函数,返回克隆出来的新的函数
     2. 新克隆出来的函数,这个函数的this被指定了

看下面例子就明白了:

let obj  = {
  name: "Thezero",
  say: function(){
    return this.name
  }
}
let obj2 = {
  name: "萤火之森"
}
console.log(obj.say.apply(obj2)); / /萤火之森
console.log(obj.say.call(obj2)); //  萤火之森
console.log(obj.say.bind(obj2)); // function(){return this.age}

手写实现call

Function.prototype.myCall = function(myThis, ...args) {
    if (typeof this !== "function") {
        throw new TypeError("not a function!");
    }
    const fn = Symbol('fn')       
    myThis= myThis|| window    
    myThis[fn] = this              
    // this指向调用call的对象,即我们要改变this指向的函数
    const result = myThis[fn](...args)  
    // 执行当前函数
    delete myThis[fn]              
    // 删除我们声明的fn属性
    return result                 
   // 返回函数执行结果
}

手写实现apply

Function.prototype.myApply = function(myThis, args = []) {
    if (typeof this !== "function") {
        throw new TypeError("not a function!");
    }
    const fn = Symbol('fn')        
    myThis= myThis|| window
    myThis[fn] = this              
    // this指向调用call的对象,即我们要改变this指向的函数
    const result = myThis[fn](...args)  
    // 执行当前函数
    delete myThis[fn]              
    // 删除我们声明的fn属性
    return result                 
    // 返回函数执行结果
}

手写实现bind

Function.prototype.myBind = function (myThis, ...args) {
    if (typeof this !== "function") {
        throw new TypeError("not a function!");
    }
    const self = this
    const fbound = function () {
        self.apply(this instanceof self ?
        this : myThis, 
        args.concat(Array.prototype.slice.call(arguments)))
    }
    // 继承原型上的属性和方法
    fbound.prototype = Object.create(self.prototype);
    return fbound;
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值