call和apply的模拟实现

call和apply都可以改变this的指向

请看下面函数的执行
var name = "hello"
var foo = {
	name: "wucr"
};
function getName(){
	console.log(this.name)
}
getName() //返回值hello
getName.call(foo) // 返回值 wucr
那么如何模拟实现一个call函数呢,请看下面分析
var foo = {
	name: "wucr",
	getName:function(){
	   console.log(this.name)
    }
}
foo.getName() // wucr

//分析以上的代码,我们可以给对象自己添加一个方法,然后去调用,但是这样就会有一个问题就是都要在对象里面去新增方法,但是我们用 delete 再删除它不就好了~,所以我们的模拟步骤可以是下面三步
1,将函数设为对象的属性
2,执行该函数
3,删除该函数

call函数第一版抹模拟实现
Function.prototype.call1 = function(context){
  context.fn = this; // 这里的this指代调用的函数
   context.fn();
   delete context.fn
}
var name = "hello"
var foo = {
	name: "wucr"
};
function getName(){
	console.log(this.name)
}
getName.call1(foo) // 返回值 wucr

我们都知道,call里面可以传递很多参数,call(context,arguments1,arguments2…),所以以上的实现不能满足,参数不固定,但是我们可以使用arguments类数组来获取参数

call函数第二版模拟实现
Function.prototype.call2 = function(context){
  var args = [];
  for(var i =1; i < arguments.length; i++){
      args.push(arguments[i])
   }
  context.fn = this; // 这里的this指代调用的函数
   context.fn(...args);
   delete context.fn
}

上面第二版没有返回值和当我们不传递context时的判断

call函数终极版模拟实现
Function.prototype.call2 = function(context){
  var context = context || window
  var args = [];
  for(var i =1; i < arguments.length; i++){
      args.push(arguments[i])
   }
   context.fn = this; // 这里的this指代调用的函数
   var result = context.fn(...args);
   delete context.fn;
   return result;
}

结合call的模拟实现apply的实现就很简单了

apply函数终极版模拟实现
Function.prototype.apply = function(context,arr){
	var context = context || window;
	context.fn = this;
	if(!arr){
		var result = context.fn()
	}else{
		var  args = [];
		 for(var i =0; i < arr.length; i++){
		      args.push(arr[i])
		   }
       var  result = eval('context.fn(' + args + ')') // 这里也可以   var result = context.fn(...args);但是这语法是es6

	}
	return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值