Prototype的bind实现

这些东西其实早几年就有人讨论了吧,没关系我写给自己看的。

http://ejohn.org/apps/learn/#2

// The .bind method from Prototype.js 
Function.prototype.bind = function(){ 
  var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift(); 
  return function(){ 
    return fn.apply(object, 
      args.concat(Array.prototype.slice.call(arguments))); 
  }; 
};

 

下面2个可以帮助你更好地理解这个函数。

一、http://www.mymickey.org/?p=97

留一个备份

prototype.js中Function.prototype.bind方法浅解

初次看到prototype.js框架里面的Function.prototype.bind = function() {}和class.create()方法实在有些不理解,因为通常mickey在使用jquery的时候并没多想这些强大的库里面为我们提供的那些及其方便使用的原型方法是如何实现的。所以在看到prototype.js此类的框架的部分源码后,对里面一些基础的类扩展原型方法的巧妙使用理解起来吃力的原因了。但是mickey经过层层分析,段段调用,因此得出了以下结论,如有不足之处请留言指正。

prototype.js中的Function.prototype.bind方法:

1
2
3
4
5
6
7
8
9
Function.prototype.bind = function() {
    var __method = this;
    var args = Array.prototype.slice.call(arguments);
    var object=args.shift();
    return function() {
        return __method.apply(object,
             args.concat(Array.prototype.slice.call(arguments)));
}
}

为所有function对象增加一个新的prototype(原型)方法bind:

  1. 将调用bind方法的对象保存到__method(方法)变量里面。
  2. 将调用bind方法时传递的参数转换成为数组保存到变量args。
  3. 将args数组的第一位[0]元素提取出来保存到变量object。
  4. 返回一个函数。

这个被返回的函数在再次被调用的时候执行如下操作:

  1. 使用apply方法将调用bind方法的函数里面的this指针替换为object。
  2. 将传递到这个匿名函数里面的参数转换为数组,与args数组组合形成一个新的数组,传递给__method方法。

var args = Array.prototype.slice.call(arguments)将这条代码简写来看可以成为这样[].slice.call(arguments);但是这样会给内存里增加一个空的数组对象,为了容易阅读点在简化可以把它假看成为这样的形式slice.call(arguments),去掉call可以假看成为这样的形式function slice(arguments){….},其实在slice就是一个为所有数组定义好的prototype方法而已它与我们自定义的原型方法不同的是,它是javascript为开发者预先定义好的内置方法,他只能被数组调用。mickey在编辑器里面alert(Array.prototype.slice)之后得到的就是funciton slice(){…}。

既然slice也只是一个普通函数方法,slice.call(object)这样让slice里面的this临时的被替换一下也是可以的。就如[].slice(){..}里面的this指针会指向调用slice方法的数组对象一样。使用call方法或apply方法可以将调用此方法的对象内的this指针临时性的改变为传递参数中的第一个参数,这一切都是临时性的,它会在函数执行完毕内存释放后重置。
var object=args.shift()将数组中的[0]位置的对象保存到object变量,这个object就是要被替换的指针。

1
2
3
4
5
6
function o(){
    this.num = 1;
    var fn = function(arg){alert(this.num+arg)}.bind(this,2);
    fn();
}
new o()

代码的第3行:一个匿名函数调用了bind方法,并传递o对象和一个数字2到bind函数里面,这两个传递过去的参数都将被转换成为数组形式,o对象会被单独提取出来放入object里。之后bind函数调用完毕,返回一个函数保存到 fn变量里边,现在fn变量里保存了bind函数的返回函数,fn里面的内容就文章第一个代码块的第五行到第七行。
代码第4行:调用fn函数,或者说是在调用bind函数的返回值。这时候会弹出数字“3”。

bind方法中的匿名函数间接保存了它运行环境里面的变量,通常这样的方法称之为“闭包”。

这在很多开源框架为开发者制作出的强大方法和属性便是这样出来的,对于初学者mickey来说以上言论如有不正确的地方还是我想还是可以勉强原谅的,如果您发现了不妥之处请留言指出。

 

二、http://stackoverflow.com/questions/1854622/prototype-bind-method-issue

posted @ 2012-11-03 10:28  e.e.p  阅读(303)  评论(0编辑  收藏  举报