上次遇到IE8不能使用bind方法就处理了一下兼容,这次分享出来,看有人能有用不?
/**
* Function.prototype.bind 方法的兼容性封装
* func 要bind的函数
* thisArg this指向对象
*/
function bind(func, thisArg) {
var nativeBind = Function.prototype.bind;//获取Function原型上的bind
var slice = Array.prototype.slice;
if (nativeBind && func.bind === nativeBind) {//表示可以直接用Function原型上的bind
return nativeBind.apply(func, slice.call(arguments, 1));
}
//走到这里就表示bind不能用,比如在IE8上就不能
/**
取func, thisArg后面的参数,比如是这样调用的bind(func,thisArg,'a',1,'c')
那slice.call(arguments, 2) 取到的就是 后面3个实参组成的数组['a',1,'c']
*/
var args = slice.call(arguments, 2);
return function () {
//args.concat(slice.call(arguments))是将bind时绑定的参数与调用时传的参数合并在一起。
var applyArgs = args.concat(slice.call(arguments));
return func.apply(thisArg, applyArgs);
};
}
来看一下使用方式:
var obj={
name:'my name is obj',
sayHi:function(){
console.log(this.name)
}
}
obj.sayHi();
var o = {
name:'my name is o'
};
var b = bind(obj.sayHi,o);
b();
在IE8 上也能正常使用,如图:
当然如果觉得这样用起来不习惯,还是比较习惯 func.bind(obj,...args) 这种方式的话,就稍作修改:
if (!Function.prototype.bind) {
Function.prototype.bind = function (thisArg) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var slice = Array.prototype.slice;
var args = slice.call(arguments, 1),
func = this;
return function () {
//args.concat(slice.call(arguments))是将bind时绑定的参数与调用时传的参数合并在一起。
var applyArgs = args.concat(slice.call(arguments));
return func.apply(thisArg, applyArgs);
};
};
}
在IE8测试也是通过的,并且加了一个参数测试 :
var obj={
name:'my name is obj',
sayHi:function(a){
console.log(this.name,"---",a)
}
}
obj.sayHi();
var o = {
name:'my name is o'
};
var b = obj.sayHi.bind(o,'ppp');
b();
结果如下: