3

可以设置函数属性的单个元素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 有一个错误要修复?

[更新]我发现使用 V8arguments.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);

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

4

3 回答 3

3

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

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

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

myclassmethod.apply(this, [].slice.call(arguments, 0).push(newValue));
于 2012-04-24T13:48:37.700 回答
0

好的,我想我们可以就此得出结论。

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

似乎 javascript 引擎的共识是,“类数组”对象的arguments行为类似于数组,但在其他方面倾向于引发一些惊喜;)无论哪种方式,ECMA 标准的解释似乎都是表面上的至少全面一致,因此语义并不是真正的问题(为什么和为什么是唯一剩下的问题,但仅具有历史意义)。

MSDN 和 Mozilla 似乎都没有这个文档(不确定 V8 或 Opera 将他们的 JS 文档隐藏在哪里)——简而言之,一些文档肯定不会出错。到那时我会退出,但是如果有人可以在某个时候机会主义地向相关方提出提示,那么偶尔使用一次是一种有用的技术。

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

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

于 2012-04-24T23:26:12.617 回答
0

ECMA-262 10.1.8 说对象的arguments原型是对象原型,并且arguments对象以某种方式初始化,使用短语“初始值”。因此,您似乎可以将其任何属性分配给您想要的任何东西。我不确定这是否是正确的解释。

于 2012-04-24T14:19:54.543 回答