对很多人来说,都知道call和bind是可以改变函数作用域的,那么很多情况下我们函数中后面用bind而为什么不用call呢,bind的出现是否多余呢?
下面就来比较一下call和bind函数执行过程中各起什么作用。
我们写一段js代码用来分析:
function $(a){
return document.getElementById(a)
}
function ab(params){
this.no=params;
this.output=function(){
alert(this.no)
}
}
function update(){
var ad=new ab("nihao");
$("div1").οnclick=ad.output.call(ad);//标注1
}
window.οnlοad=update();
上面代码估计大家都能看得懂,如果不用call方法改变作用域那么就可以写成$("div1").οnclick=ad.output,但是这时候output中的this指
向的是div元素本身,div本身是没有this.no成员属性的,所以就会弹出undefind。
利用call方法将ouput作用域指向ad,这时候output中的this就指向了ad,从而实现我们想要的作用域,也会弹出我们想要的结果了。
但是这种写法$("div1").οnclick=ad.output.call(ad);相当于$("div1").οnclick=do();在赋值实例的时候直接就执行了该函数。
也就是上面写法虽然达到我们想要结果,不过在页面加载之后就已经执行了一遍onclick事件。
通常我们发送一段请求结束后会组织页面元素,然后给页面元素一些click等事件,或者页面加载时候给元素些事件。但是我们给这
些事件时候肯定不会希望在请求结束后立即就去执行,
这个时候我们就用到bind了也就是传说中的函数绑定,函数绑定的作用就是在特定的环境中以指定参数去调用另一个函数,通常在
事件处理程序中作为变量进行传递同时保留其代码执行环境
比较绕口吧。说白了就是利用bind来代替call时候既能实现call的改变作用域效果,又能将该函数作为一个变量似的传递给事件处理程
序(变量是不会被执行的),此时浏览器只是解析了该函数而没有去执行。相当于ab.output(没改变作用域)
那么修改以上代码标注1部分如下:
$("div1").οnclick=ad.output.bind(ad);//标注1
这样就达到我们期待效果了。