js bind

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.封装(可以通过这样的方式封装自己喜欢的公用的函数)

 

原文地址:https://www.cnblogs.com/zycbloger/p/5567873.html