var Bind = function(object, fun) {
var args = Array.prototype.slice.call(arguments).slice(2);
return function() {
return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
}
}1.我知道Array.prototype.slice这貌似是扩展数组的原始方法。
但是Array.prototype.slice.call(arguments)是什么意思?
这里的arguments是调用slice的时候还是调用Bind的时候传进去的参数???
Array.prototype.slice.call(arguments).slice(2);
这一整句又是什么意思?
我真的很晕
2.args.concat(Array.prototype.slice.call(arguments));
这一句又是什么意思?这段代码是做什么用的?求解释。

解决方案 »

  1.   

    这段是改变对象的作用域时候用的吧
    Array.prototype.slice.call(arguments)在arguments对象上调用 数组的slice方法
    Array.prototype.slice.call(arguments).slice(2)返回一个arguments中的子数组
    args.concat(Array.prototype.slice.call(arguments));把子数组与原有的arguments连接起来
    这么操作估计是想在转移过程中保持参数不变吧<input type="button" id="x" />
    <input type="button" id="y" />
    <script type="text/javascript">
    var Bind = function(object, fun) {
        var args = Array.prototype.slice.call(arguments).slice(2);
        return function() {
            return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
        }
    }
    var o = new Object()
    o.f=function(){alert(this)};
    document.getElementById("x").onclick=o.f;
    document.getElementById("y").onclick=Bind(o,o.f);
    </script>
      

  2.   

    这个是函数式编程中的套用,所谓套用就是将一个接受多个参数的函数
    进行包装,返回一个需要输入的参数个数较少的新函数,使其更方便
    使用.
    function add(){
        var i, args = arguments, len = args.length, sum = 0;
        for(i=0; i < len; i++){
            sum += i;
        }
        return sum;
    }function curry(fn){
        var args = [].slice.call(arguments, 1);
        return function(){
            var moreArgs = [].slice.apply(arguments)
            return fn.apply(null, args.concat(moreArgs ));
        }
    }var fn = curry(add, 1, 2, 3);//产生一个可以不用反复输入前三个参数的新函数
    alert(fn(4,5,6));
      

  3.   

    js中的数组具有concat方法, 该方法会在当前数组的基础上追加元素形成一个新数组返回。concat的参数中
    可以包含数组,若为数组的话会依次将数组中的内容展开后再追加。但是有一点比较麻烦arguments并不是一个
    数组元素,所以需要将其转化为一个数组。转化的方法就是调用:Array.prototype.slice.call(arguments)
      

  4.   

    字面上的解释就是将一个对象绑定到一个函数,本质上就是改变这个函数运行时上下文环境,主要就是改变函数里的this.类库差不多都有这方法。第一个arguments为被用Bind时的,其它的如1楼所述。2楼的说法不太对。
      

  5.   


    <script type="text/javascript">      var Bind = function (object, fun) {
              var args = Array.prototype.slice.call(arguments).slice(2);
              return function () {
                  return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));
              }
          }      //首先说下arguments
          //对于每个函数它都有个隐形的参数,就是arguments,它是个数组
          //例如
          function a(p1) {
            alert(arguments[0])
        }
          a(1)//输出1
          function b(p1,p2){
              alert(arguments[0] + ',' + arguments[1])
          }
          b(1,2)//输出(1,2)      //arguments 它的类型是Array,但它是个特殊的Array,它没有slice方法      //Array.prototype.slice.call(arguments)这句是扩张arguments,给它一个slice方法,      //然后调用刚刚扩张出来的slice(2)方法,取得函数function(object,fun) 第二个参数后面的所有参数。      //args.concat 这个是合并两个数组的意思,把args 和 arguments 合并起来      //return fun.apply(object, args.concat(Array.prototype.slice.call(arguments)));      //这个的意思,就是把所有参数传入到 fun 这个数里面,所有的参数包括(之前的args,还有后面args.concat的)      //这个函数的作用域是Object(至于作用域和call,apply 可以搜索相关资料)      //最后举个例子,例如,有两个人,一个是645,男,一个是abc,女
          var obj = {
              name: '645',
              sex:true,//男
              say: function () {//自我介绍
                  if (this.sex) {
                      alert('Hi my name is ' + this.name + ' ,I am boy');
                  }
                  else {
                      alert('Hi my name is ' + this.name + ' ,I am girl');
                  }
              }
          };
          obj.say(); //输出 'Hi my name is 645 I am boy'      //下面我换人了,但是没有加性别
          var obj2 = {
            name:'abc'
          }
          //把这些变更,绑定到say函数上
        var fn = Bind(obj2, obj.say, false)//这个性别改成flase,为女,注意,false(性别女)也传入到函数里了,这里是关键    fn(); //输出 'Hi my name is abc I am girl'
          
          //有说的不对的,望高人指正
          
      </script>
      

  6.   


    这里有很多不对的地方,
    首先arguments不是数组,为object。你可以看Object.prototype.toString.call(arguments)的结果是[object Object]而不是[array Object],同样你可以用constructor去验证,一个简单的就是你可以直接打印出一个数组,而arguments你是打印不出来的。
    第二,“Array.prototype.slice.call(arguments)这句是扩张arguments,给它一个slice方法”,Array.prototype.slice.call(arguments)不是扩张arguments,而是在arguments这个object下执行Array的slice方法,返回一个数组,这个数组的元素是arguments里能用数字索引到的,如果arguments[0];这时再接一个slice(2),前面的以经返回了一个数组,就和[1,2,3].slice(2)一样了,不是什么扩张出来的slice,跟本没有这种说法。Array.prototype.slice.call(arguments).slice(2)可以写成Array.prototype.slice.call(arguments,2);
      

  7.   

    为何curry不这样
    function curry(fn){
        var args = [].slice.call(arguments, 1);
    return fn.apply(null,args);
    }
      

  8.   

    如果象你那样用的话,返回的是函数的执行结果,就失去了套用的本意。
    套用的本意就是将一个原本可以输入多个参数的函数进行加工,使其中的
    前几个参数固定下来,使更便于使用。
    就好比有一个函数
    fn(n1, n2, n3, n4){}
    如果你需要连续调用n次,且每次前三个参数都一样,那么你可以这样:
    fn(1, 2, 3, 0);
    fn(1, 2, 3, 1);
    fn(1, 2, 3, 2);
    fn(1, 2, 3, 3);
    fn(1, 2, 3, 4);
    ……如果你不嫌麻烦,你可以那样用,而且好理解。但是如果你想偷懒的话
    可以对函数进行下包装。
    var fn2 = curry(fn);
    fn2(0);
    fn2(1);
    fn2(2);
    fn2(3);
    ……
    两种风格实现的功能一样,就看你喜欢那一种了。
      

  9.   

    解释的太详细了,明白了,星期六的黄昏,谢谢了,嘿嘿。
    这个sum += i;应该是sum += arguments[i];
      

  10.   

    那在这个环境里边呢:
    http://topic.csdn.net/u/20090319/01/ec60caf1-af16-47b5-a89b-bb91e1c5c6e2.html
    这个幻灯片切换里边的代码Bind方法的用意似乎和星期六的黄昏解释的不一样。