在javascript中调用并应用

时间:2012-10-22 02:35:41

标签: javascript

  

可能重复:
  What’s the meaning to chain call and apply together?

我发现了一些像这样的代码:

function fun() {
    return Function.prototype.call.apply(Array.prototype.slice, arguments);
}

我知道js中的callapply,但是当他们聚在一起时我很困惑。

然后我想知道是否

Function.prototype.call.apply(Array.prototype.slice, arguments)

与:

相同
Array.prototype.slice.apply(arguments);

如果没有,第一行会做什么?

2 个答案:

答案 0 :(得分:10)

好吧,让我们通过替换来解决这个问题。我们从:

开始
Function.prototype.call.apply(Array.prototype.slice, arguments);

我们所知道的:

  1. Function.prototype.call是一个功能。
  2. this call指针指向Function.prototype
  3. 我们使用applythis call指针更改为Array.prototype.slice
  4. arguments 已应用(未作为参数传递)至call
  5. 因此,上述陈述相当于:

    Array.prototype.slice.call(arguments[0], arguments[1], ...);
    

    从中我们看到:

    1. Array.prototype.slice是一个功能。
    2. this slice指针指向Array.prototype
    3. 我们使用callthis slice指针更改为arguments[0]
    4. arguments[1], ...作为参数传递给slice
    5. 这与:

      相同
      arguments[0].slice(arguments[1], ...);
      

      这样做的好处是我们在一行中为slice创建fast unbound wrapper

      编辑:创建快速未绑定包装器的更好方法如下(请注意,它可能在某些较旧的浏览器中不起作用,但您现在不需要担心 - 您可能对于不支持bind的浏览器,请始终使用shim

      var slice = Function.prototype.call.bind(Array.prototype.slice);
      

      这与:

      相同
      function slice() {
          return Function.prototype.call.apply(Array.prototype.slice, arguments);
      }
      

      工作原理:

      1. Function.prototype.call是一个功能。
      2. this call指针指向Function.prototype
      3. 我们使用bindthis call指针更改为Array.prototype.slice
      4. bind会将arguments 已应用的函数返回给call
      5. 奖金:如果您的编程风格功能强大,就像我的一样,那么您会发现这段代码非常有用:

        var funct = Function.prototype;
        var obj = Object.prototype;
        var arr = Array.prototype;
        
        var bind = funct.bind;
        
        var unbind = bind.bind(bind);
        var call = unbind(funct.call);
        var apply = unbind(funct.apply);
        
        var classOf = call(obj.toString);
        var ownPropertyOf = call(obj.hasOwnProperty);
        var concatenate = call(arr.concat);
        var arrayFrom = call(arr.slice);
        
        1. 使用此功能,您可以使用callapply轻松创建未绑定的包装。
        2. 您可以使用classOf获取值的内部[[Class]]
        3. 您可以在内部使用ownPropertyOf进行循环播放。
        4. 您可以使用concatenate加入数组。
        5. 您可以使用arrayFrom创建数组。

答案 1 :(得分:1)

使用以下行,.apply调用.call方法,调用上下文.call.slice方法,并传递arguments个集合作为个人论点。

Function.prototype.call.apply(Array.prototype.slice, arguments);

这有效地为我们提供了这个:

Array.prototype.slice.call(arguments[0], arguments[1], arguments[2] /*, etc */);

这意味着.slice()将被调用,arguments对象中的第一项作为调用上下文,其余参数作为普通参数。

所以如果arguments的内容是这样的话:

myarray, 0, 5

你有效地结束了这个:

myarray.slice(0, 5)

这基本上是一种不必这样做的方式:

var arr = arguments[0];
var rest = Array.prototype.slice(arguments, 1);

var result = arr.slice.apply(arr, rest);