原生JavaScript模拟Function.prototype.bind

大部分高级浏览器都实现了内置的Function.prototype.bind,用来指定函数内部的this指向(呵呵,这句话倒是有“针对”IE的嫌疑…),这用在尤其是回调函数上面,屡试不爽。
即使没有原生的Function.prototype.bind,我们来模拟实现一个也不是什么难事:
比如

Function.prototype.bind=function(context){
	var self=this;   //保存原‘函数’
	return function(){
		return self.apply(context,argument);
	}
};

var obj={
	name:'sven';
};
var func=function(){
	alert(this.name);
}.bind(obj);
func();   //'sven'

我们通过Function.prototype.bind来“包裹”func函数,并且传入一个对象context当做参数,这个context对象就是我们想修正的this对象。

Function.prototype.bind 的内部实现中,我们先把 func 函数的引用保存起来,然后返回一个新的函数。当我们在将来执行 func 函数时,实际上先执行的是这个刚刚返回的新函数。在新函数内部,self.apply(context, arguments)这句代码才是执行原来的 func 函数,并且指定 context对象为 func 函数体内的 this所指向的对象。

这是一个简化版的 Function.prototype.bind 实现,通常我们还会把它实现得稍微复杂一点,使得可以往 func 函数中预先填入一些参数:

Function.prototype.bind=function(context,auguments){
	var self=this,                          //保存原‘函数’
		context=[].shift.call(arguments),   //需要绑定的this上下文
		args=[].slice.call(arguments);      //剩余的参数转成数组
	return function(){
		return self.apply(context,[].concat.call(args,[].slice.call(arguments)));
		//执行新的函数的时候,会把之前传入的context当做新函数体内的this
		//并且组合两次分别传入的参数,作为新函数的参数
	}
};

var obj={
	name:'sven'
};
var func=function(a,b,c,d){
	alert(this.name);
	alert([a,b,c,d]);
}.bind(obj,1,2);
func(3,4);

想必你也看出来了:所谓call & apply,说得更“通俗”一点,不过是把对象内部暴露出来。或者说,去遍历对象的属性!

这样的话,大概好理解一些了吧。

发布了195 篇原创文章 · 获赞 391 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_43624878/article/details/103816703
今日推荐