1)我有以下代码:
var callIt = function(fn) { return fn.apply(this, Array.prototype.slice.apply(arguments, 1)); };
当在nodejs中调用callIt时,它会抱怨:
return fn.apply(this, Array.prototype.slice.apply(arguments, 1));
^
TypeError: Function.prototype.apply: Arguments list has wrong type
2)如果我将callIt更改为:
var callIt = function(fn) { return fn.apply(this, Array.prototype.slice.apply(arguments)); };
Nodejs没有抱怨,但结果不是预期的,传递了额外的第一个参数。
3)如果我将callIt更改为:
var callIt = function(fn) { var args = Array.prototype.slice.apply(arguments); return Function.prototype.apply(fn, args.slice(1)); //return fn.apply(this, args.slice(1)); //same as above };
它按预期工作。
4)如果我在Chrome开发者工具控制台中运行测试,请执行以下操作:
> var o={0:"a", 1:"asdf"} undefined > o Object 0: "a" 1: "asdf" __proto__: Object > Array.prototype.slice.call(o,1) [] > Array.prototype.slice.call(o) []
现在切片不适用于类似数组的对象。
我对这些感到困惑。请解释一下。
我引用了以下内容: Array_generic_methods
答案 0 :(得分:5)
你的问题是apply
method of functions期望一个数组作为它的第二个参数 - 就是你的TypeError来自的地方,你传递了1
。相反,请使用[1]
或更好的call
method:
fn.apply(this, Array.prototype.slice.call(arguments, 1));
它在{0:"a", 1:"asdf"}
上不起作用的原因是它不是类似于数组的对象 - 它没有length
属性。 [].slice.call({0:"a", 1:"asdf", length:2}, 0)
会这样做。