1.作用
函数的bind方法用于将函数体内的this绑定到某个对象,然后返回一个新函数。 //bind 相比于call apply this 都等于 obj; bind是产生一个新的函数 不执行,call apply 立即执行
Fn.bind(obj, arg1, arg2,...);
Fn.bind(obj) //新的函数 function () { [native code] } 看不到
Fn.bind(obj) (); //执行函数 类似:a=function(){}; 执行 a(); 一个道理
2.实例
var Fn = function(){ console.log(this); } var obj = {a:1}; Fn(); -> window //在浏览器环境 Fn.bind(obj) -> function () { [native code] } //得到新的函数 Fn.bind(obj)(); -> Object {a: 1} //执行结果 console.log(this); this = obj
3.绑定参数
function add(x,y) { return x+y; } var plus5 = add.bind(null, 5); //把第一个参数给绑进去 plus5(10) // 15 5+10 = 15
3.注意
bind每次运行都会产生新的函数,所以在用的时候要小心
element.addEventListener('click', Fn.bind(obj)); //在点击的时候,每次都会产生一个新的函数 element.removeEventListener('click', Fn.bind(obj)); //移除事件的时候就会无法取消绑定 //正确的方法 var listener = Fn.bind(obj); element.addEventListener('click',listener ); element.removeEventListener('click', listener );
4.兼容
bind方法在ie8以下都不支持, 自定义bind如下
if(!('bind' in Function.prototype)){ //Function如果没有bind方法的话 Function.prototype.bind = function(){ //Function原型添加bind var fn = this; //引用bind的函数 var context = arguments[0]; //obj 第一个参数 var args = Array.prototype.slice.call(arguments, 1); //去掉第一个参数 同等arguments.slice(1); 前面的写法 防止slice 被改过 return function(){ //返回一个新的fun return fn.apply(context, args); // fn 上层的this 指的是引用bind的函数 } } }
5.延伸
Fn.bind(obj) --> obj = 函数function
执行完后 新Fn的this = 函数function
slice 是 Array 构造函数 的一个方法
[1, 2, 3].slice(0, 1);
->[1]
Array.prototype.slice.call([1,2,3], 0, 1); //把Array.prototype.slice 方法 的this 指向 [1,2,3] 也就是 this = [1,2,3];
->[1]
Function.prototype.call.bind(Array.prototype.slice)([1, 2, 3],0,1);
也可以这样表示:
var slice = Function.prototype.call.bind(Array.prototype.slice);
slice([1, 2, 3],0,1);
->[1]
得到同样的结果
原理:
.bind的作用是把引用函数的this指向 obj , 并生成一个新的函数。
这里的引用的函数是Function.prototype.call这个函数,通过bind 把this 指向 Array.prototype.slice 这个函数, 然后新生成一个函数。 如:我们通过定义 var slice = 新函数 ;
这个新的函数 里的 this = Array.prototype.slice;
我们执行slice([1, 2, 3],0,1) 的时候,事实上他是执行call([1, 2, 3],0,1),只是call里的this = Array.prototype.slice;
var obj={ x:10, y:5 }; var fn = function(){ return this.x + this.y; }; Function.prototype.call.bind(fn)(obj); ->15
个人看法:通过这种方式可以
1.扩展对象的方法(如果有构造函数的话,可以直接在构造函数上加入,直接了当,但是通过这种方式扩展的话可以保持原有构造函数的统一性;)
2.封装(可以通过这样的方式封装自己喜欢的公用的函数)