js手动实现call,apply,bind

原文https://www.jianshu.com/p/3b69fb0d4c2f 

 

我也不知道为什么只能显示一部分  好气哦  看原文吧 

先分析下3个方法的作用

  • 改变this的指向。
  • 传入参数。
  • call apply返回函数结果, bind 返回新函数

call

改变this的指向 

首先我们知道,对象上的方法,在调用时,this是指向对象的。

let o = {
    fn:function(){
        console.log(this);
    }
}
o.fn() //  Object {fn: function}  

 

// 函数原型上添加 myCall方法 来模拟call
Function.prototype.myCall = function(obj){
    //我们要让传入的obj成为, 函数调用时的this值.
    obj._fn_ = this;  //在obj上添加_fn_属性,值是this(要调用此方法的那个函数对象)。
    obj._fn_();       //在obj上调用函数,那函数的this值就是obj.
    delete obj._fn_; // 再删除obj的_fn_属性,去除影响.
    //_fn_ 只是个属性名 你可以随意起名,但是要注意可能会覆盖obj上本来就有的属性
}

下面测试一下

let test = {
    name:'test'
}
let o = {
    name:'o',
    fn:function(){
        console.log(this.name);
    }
}
o.fn() // "o"
o.fn.call(test) // "test"
o.fn.myCall(test) // "test"

传入参数

  • 最简单实现,用ES6
// 只需要在原来的基础上 用下拓展运算符 剩余运算符即可
Function.prototype.myCall = function(obj,...arg){
    obj._fn_ = this;
    obj._fn_(...arg);
    delete obj._fn_;
}
//测试
let test = {
    name:'test'
}
let o = {
    name:'o',
    fn:function(){
        console.log(this.name, ...arguments);  //这里把参数显示一下
    }
}
o.fn(1,2,3) // "o" 1 2 3
o.fn.call(test,1,2,3) // "test" 1 2 3
o.fn.myCall(test,1,2,3) // "test" 1 2 3
// 没问题
  • 用eval 方法
    eval方法,会对传入的字符串,当做JS代码进行解析,执行。
Function.prototype.myCall = function(obj){
    let arg = [];
    for(let i = 1 ; i<arguments.length ; i++){
        arg.push( 'arguments[' + i + ']' ) ;
        // 这里要push 这行字符串  而不是直接push 值
        // 因为直接push值会导致一些问题
        // 例如: push一个数组 [1,2,3]
        // 在下面
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值