我发现了一些像这样的代码:
function fun() {
return Function.prototype.call.apply(Array.prototype.slice, arguments);
}
我知道js中的call
和apply
,但是当他们聚在一起时我很困惑。
然后我想知道是否
Function.prototype.call.apply(Array.prototype.slice, arguments)
与:
相同Array.prototype.slice.apply(arguments);
如果没有,第一行会做什么?
答案 0 :(得分:10)
好吧,让我们通过替换来解决这个问题。我们从:
开始Function.prototype.call.apply(Array.prototype.slice, arguments);
我们所知道的:
Function.prototype.call
是一个功能。this
call
指针指向Function.prototype
。apply
将this
call
指针更改为Array.prototype.slice
。arguments
已应用(未作为参数传递)至call
。因此,上述陈述相当于:
Array.prototype.slice.call(arguments[0], arguments[1], ...);
从中我们看到:
Array.prototype.slice
是一个功能。this
slice
指针指向Array.prototype
。call
将this
slice
指针更改为arguments[0]
。arguments[1], ...
作为参数传递给slice
。这与:
相同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);
}
工作原理:
Function.prototype.call
是一个功能。this
call
指针指向Function.prototype
。bind
将this
call
指针更改为Array.prototype.slice
。bind
会将arguments
已应用的函数返回给call
。奖金:如果您的编程风格功能强大,就像我的一样,那么您会发现这段代码非常有用:
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);
call
或apply
轻松创建未绑定的包装。classOf
获取值的内部[[Class]]
。ownPropertyOf
进行循环播放。concatenate
加入数组。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);