4

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)
[]

现在 slice 不适用于类似数组的对象。

我对这些感到困惑。请解释。

我引用了以下内容: Array_generic_methods

4

1 回答 1

5

你的问题是apply函数的方法需要一个数组作为它的第二个参数——这就是你的 TypeError 来自哪里,你传递了1. 相反,使用[1]或更好的call方法

fn.apply(this, Array.prototype.slice.call(arguments, 1));

The reason why it didn't work on {0:"a", 1:"asdf"} is that this is not an array-like object - it has no length property. [].slice.call({0:"a", 1:"asdf", length:2}, 0) would do it.

于 2013-02-14T08:40:37.083 回答