对于Function.prototype.bind的解释,我觉得可以这么说:.bind()创建了一个函数,当这个函数在被调用的时候,它里面的 this 关键词会被设置成被传入的参数。
下面举例一个使用.bind()方法实现动态绑定函数的例子。
(1)有一个案件查询列表页面,页面的主要功能是实现案件的查询,然后以列表的方式展示案件。可以对列表的单个案件进行选择操作,当用户选择了案件后,调用列表页面的selectAjxx(),会把案件的信息封装成JavaScript对象作为方法的返回值。
(2)由于有多个业务模块调用这个案件查询页面,而且每个模块调用完这个方法获得选择的案件信息后,处理的操作会有不同。比如有的模块只提取案件的案号用,有的模块需要提取案件的全部信息。
那么问题来了,如何实现每个模块的操作相互独立,难道要在selectAjxx()加很多个if–else判断,每个模块有一个 if判断吗???? 看着不太专业哈,而且也不太好维护,我们应该尽量保持开闭原则,也就是对扩展开放,对修改是关闭的,不允许的。
下面就是我的实现思路,应用Function.prototype.bind巧妙的实现动态绑定。
<script>
/************ 每个模块不同的回调操作 ************/
function callbackObj(params){
this.params = params;
}
callbackObj.prototype.doCallBack = function (){
//不同模块写自己的回调操作。。。。。。
alert(this.params.name);
}
function getcallbackObj(params){
return new callbackObj(params);
}
/************ 每个模块不同的回调操作 ************/
/****** 多个模块公用同一个控件,但是后续操作各有不同 *******/
var callback = function (){
this.doCallBack();
}
function selectAjxx(){
var params = {ah:"2105年民初字第1001号",cbr:"坛主叭叭叭"};
var obj = window.openner.getcallbackObj(params);
var someOneCallback = callback.bind(obj);
someOneCallback();
}
</script>
每个模块实现自己的回调操作,并且提供一个获得回调实例的方法getcallbackObj()。
列表页面的callback对象里的this就是需要动态绑定的对象。
注意:IE8不支持bind哈,需要自己进行扩展。支持的浏览器有Chrome 7+,Firefox 4.0+,IE 9+,Opera 11.60+,Safari 5.1.4+。虽然IE 8/7/6等浏览器不支持,但是Mozilla开发组为老版本的IE浏览器写了一个功能类似的函数,代码如下:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
ok,结贴。