如果n大于正式或实际参数的数量,那么“arguments [n]的状态不能设置”bug?

时间:2012-04-24 13:28:47

标签: javascript

可以设置函数arguments属性的各个元素(Mozilla称之为'类似数组'的属性),但是Mozilla报告在SpiderMonkey 1.5中无法向此属性添加元素,尽管这样固定在1.6(参见SpiderMonkey的注释...... https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments)。

这是一个有用的属性,从子类链接构造函数,创建传递给函数的参数列表(例如,myclassmethod.apply(this, arguments))等。

但是我发现V8不会像Mozilla报道的SpiderMonkey 1.5那样延长长度。 (不确定其他JavaScript引擎,Opera,Rhino等的状态。)

这实际上是ECMA功能吗? Mozilla是否认为这是一个错误,或者V8是否有错误需要修复?

[更新]我发现使用V8可以分配arguments.length属性,因此有效arguments可以扩展(或设置为你需要的任何长度)。但是JSLint确实抱怨这是一个糟糕的任务。

[更新]一些测试代码,如果有人想在Opera,FF等中尝试这个,创建一个子类的实例,用一个arg调用构造函数,同时在子类构造函数中向arguments添加一个元素并调用超类构造函数,超类应报告两个参数:

function MyClass() {
    if (arguments.length) {
        console.log("arguments.length === " + arguments.length);
        console.log("arguments[0] === " + arguments[0]);
        console.log("arguments[1] === " + arguments[1]);
    }
}

function MySubClass() {
    console.log(arguments.length);
    //arguments.length = 2;  // uncomment to test extending `length' property works
    arguments[1] = 2;
    MyClass.apply(this, arguments);
}

MySubClass.prototype = new MyClass();

new MySubClass(1);

[更新]当您通过外观(arguments)对arguments[0] = "foo"进行任何类型的分配时,JSLint实际上会抱怨。所以也许JSLint也有一些工作要做。

3 个答案:

答案 0 :(得分:2)

不确定这是否是您要找的,但您可以将arguments对象变为标准数组:

var args = [].slice.call(arguments, 0);

[编辑]所以你可以这样做:

myclassmethod.apply(this, [].slice.call(arguments, 0).push(newValue));

答案 1 :(得分:0)

ECMA-262 10.1.8说arguments对象的原型是Object原型,并且使用短语“initial value”以某种方式初始化arguments对象。所以,看起来您可以将任何属性分配给您想要的任何属性。我不确定这是否是正确的解释。

答案 2 :(得分:0)

好的,我想我们可以就这一点作出结论。

在FF,Comodo Dragon,Opera和IE(所有当前版本,Windoze)上运行上面的示例代码,他们都会接受更改arguments.length属性以调整大小(如Mozilla的短语,'array-喜欢')arguemnts对象。 None将通过为数组指定一个通常的值来增加大小(即arguments[arguments.length] = "new arg")。

似乎javascript引擎的共识是,像'数组一样'的对象arguments表现得像一个数组,但另外倾向于抛出一些惊喜;)无论哪种方式解释ECMA标准看起来它至少在整体上是一致的,所以语义不是真正的问题(为什么和为什么是唯一剩下的问题,但只有历史利益)。

MSDN和Mozilla似乎都没有记录(不确定V8或Opera隐藏他们的JS文档的位置) - 简而言之,总结一些文档肯定不会出错。在这一点上,我会屈服,但是如果有人可能在某些时候机会性地将暗示放弃到相关方面,那么偶尔使用它是一种有用的技术。

感谢所有花时间看这个问题的人。

[更新] BishopZ上面已经指出.apply无论如何都会采取一系列论点(自从我多年前使用它以来解决了我的问题以来,这已经让我大吃一惊)。然而,仍然可以使用'类似数组'arguments,在某些情况下甚至可能更好(例如更容易将值弹出到或者只是将参数传递给超类)。再次感谢您查看此问题。