实现call、apply 及 bind 函数

1.call 函数的实现步骤:

引入:

 function person() {
    console.log(this.name);
  }
  var egg = {name:'蛋老师'};
  person.call(egg);  //函数调用了call方法并且把this绑定到egg对象上;

用call进行绑定,就相当于在egg对象中增加了一个person函数,其实这里就是this的隐式绑定,
当函数person引用有上下文对象时,就会把函数person调用中的this绑定到这个上下文对象egg了,总的来说就是this指向调用者

  var egg = {
    name:'蛋老师'
    person:function() {
    console.log(this.name);
  }
    };
  egg.person();

要实现call方法,就要思考call是从哪里来的

  • 每个JavaScript函数其实都是Function对象,而Function对象是构造函数,构造函数是有原型对象的,也就是Function.prototype
  • 这个原型对象里有很多属性可以使用,比如call就是在这个原型对象属性里面来的,
  • 因此我们要模仿必须在原型对象里面添加新的和call一样的属性,call作为一种属性同时也是一种方法,可以看到在调用call时,后面加了括号
  • 既然是方法,那call其实就是一个函数而已,我们可以为原型对象添加一个新的方法
function person(a,b,c,d) {
  return {
    name: this.name,
    a:a,b:b,c:c,d:d
  }
}

var egg = {name:'蛋老师'};

Function.prototype.newCall = function (obj) {
  if(typeof this !== "function"){
    console.error("type error");
  }
  var obj = obj || window; //如果对象存在就不管了,如果对象不存在就执行window
  obj.p = this;  //这里开始还没有硬绑定,依旧是隐式绑定,this指向调用者person

  var newArguments = [...arguments].slice(1);
  var result = obj.p(...newArguments);
  delete obj.p;  //要把方法删除,因为不能改写来对象
  return result
}
var bibi = person.newCall(egg,'点赞','收藏','转发','充电');
console.log(bibi)
2.apply 函数的实现步骤:

apply第二个参数需要传入数组需要判断两种情况:

  • 数组为空,直接调用
  • 数组不为空,传入形参调用
function person(a,b,c,d){
	 return{
	      name: this.name,
	      a:a,b:b,c:c,d:d
	    }
}

 var egg = {name:'蛋老师'};

 Function.prototype.newApply = function(obj){
 	var obj = obj || window;
 	obj.p = this;
 	if(!argumnets[1]){
 		result = obj.p();
 	}else{
 		result = obj.p(...arguments[1])
 	}
 	delete obj.p;
 	return result;
 }
  var bibi = person.newCall(egg,['点赞','收藏','转发','充电']);
  console.log(bibi)
3.bind 函数的实现步骤:

bind与apply和call不同,bind会返回一个函数
bind是具有柯里化特性的

function person() {
   return{
    name: this.name,
    a:a,b:b,c:c
  }
}
var egg = {name:'蛋老师'};

Function.prototype.newBind = function(obj){
	var that = this,
	      arr = [...arguments].slice(1);
	return function(){
		var arr2 = [...arguments],
		      arrSum = arr.concat(arr2);
		 return that.apply( 
			 this instanceof that ? this : obj,
			 arrSum);
	}
}
person.newBind(egg,'点赞','投币')('充电');
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值