好吧,让我们通过替换来解决这个问题。我们从以下开始:
Function.prototype.call.apply(Array.prototype.slice, arguments);
我们所知道的:
-
Function.prototype.call
是一个函数。
- The
this
的指针call
指着Function.prototype
.
- We use
apply
改变this
的指针call
to Array.prototype.slice
.
-
arguments
is applied(不作为参数传递)到call
.
因此上面的语句等价于:
Array.prototype.slice.call(arguments[0], arguments[1], ...);
由此我们看出:
-
Array.prototype.slice
是一个函数。
- The
this
的指针slice
指着Array.prototype
.
- We use
call
改变this
的指针slice
to arguments[0]
.
-
arguments[1], ...
作为参数传递给slice
.
这与:
arguments[0].slice(arguments[1], ...);
这样做的好处是我们正在创建一个快速未绑定包装器 for slice
在一行中。
Edit:创建快速未绑定包装器的更好方法如下(请注意,它可能无法在某些较旧的浏览器中工作,但您现在实际上不需要担心 - 您可能总是使用shim对于不支持的浏览器bind
):
var slice = Function.prototype.call.bind(Array.prototype.slice);
这与:
function slice() {
return Function.prototype.call.apply(Array.prototype.slice, arguments);
}
怎么运行的:
-
Function.prototype.call
是一个函数。
- The
this
的指针call
指着Function.prototype
.
- We use
bind
改变this
的指针call
to Array.prototype.slice
.
-
bind
返回一个函数,其arguments
are applied to call
.
Bonus:如果您的编程风格是高度实用的,就像我的一样,那么您会发现这段代码非常有用:
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
or apply
.
- 您可以使用
classOf
以获得内部[[Class]]
的一个值。
- 您可以使用
ownPropertyOf
在 for in 循环内。
- 您可以使用
concatenate
加入数组。
- 您可以使用
arrayFrom
创建数组。