理解call和实现call

js里对call的定义:

调用一个对象的一个方法,以另一个对象替换当前对象。call方法接受以下参数(obj,argument1,argument2,...)。

我们用call写一个小demo:

如上图我们就可以很直观的理解js对call的定义。调用window对象下的fn方法,用obj对象替换了window对象。可能这句话理解还是有些歧义,我们之后再解释。

为什么说obj对象替换了window对象?见图:

我们从代码里看到直接调用fn输出window下的name。因为fnwindow对象下,kack也在window下。 当我们用call的时候,把window对象替换成了obj,所以输出了obj的name:'tom'

对于call的实现分析:

  1. call改变了this指向;
  2. 调用的方法执行了;
  3. call接受多个参数;

问题一:我们如何改变一个方法的this的指向呢? 问题二:如何去改变this指向,有去调用这个方法? 问题三:如何接受多个参数?再去执行?

可以看到我们给一个对象添加一个fn1属性,并把fn方法赋给这个属性,就相当于改变了fn里的this指向!然后再调用obj.fn1这个属性,不就执行了fn方法吗?是不是很简单~ 那多出来的fn1属性怎么办?也很简单,把这个对象的属性删除不就可以么。。。那多个参数怎么办?我们获取一个方法的参数可以通过arguments来获取,arguments是一个伪数组对象。然后遍历这个对象把属性再放到一个数组里,这样就可以取出来了。 最后一个问题:得到参数数组后怎么放到方法里去执行呢?我们要用到eval()函数,eval()函数可计算某个字符串,并执行其中的的 JavaScript 代码。

我们先按上面的分析实现call:

Function.prototype._call = function(){
    var args = [];
    var obj = arguments[0] || window; // call 如果第一个参数传null,则这个对象是window
    for(var i=1, len = arguments.length; i < len; i++){
        // 因为执行一个函数传参一般都是传string类型,所以此处需要用字符串拼接,之后用eval去解析这个字符串。
        args.push('arguments['+ i +']''); 
    }
    obj.fn = this; // this就是调用_call的函数
    // args = ['arguments[1]', 'arguments[2]', 'arguments[3]', ...];
    // 此处执行eval时,会先调用args.toString(),然后执行eval时会从对应的arguments对象中取参数。
    eval('obj.fn(' + args +')');
    delete obj.fn;
};
复制代码

运行以上代码:

大功告成,可以看出我们实现了call方法!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值