arguments 对象是不是应该是 ES6 中的可迭代对象?

Posted

技术标签:

【中文标题】arguments 对象是不是应该是 ES6 中的可迭代对象?【英文标题】:Is the arguments object supposed to be an iterable in ES6?arguments 对象是否应该是 ES6 中的可迭代对象? 【发布时间】:2016-04-09 10:52:18 【问题描述】:

在 ES6 中,当传递给 Set 构造函数时,我试图将 arguments 对象用作可迭代对象。它在 IE11 和 Chrome 47 中运行良好。它在 Firefox 43 中不起作用(抛出TypeError: arguments is not iterable)。我查看了 ES6 规范,并不能真正找到 arguments 对象是否应该是可迭代对象的定义。

这是我尝试做的一个例子:

function destroyer(arr) 
  var removes = new Set(arguments);
  return arr.filter(function(item) 
    return !removes.has(item);
  );


// remove items 2, 3, 5 from the passed in array
var result = destroyer([3, 5, 1, 2, 2], 2, 3, 5);
log(result);

仅供参考,我知道此代码有多种解决方法,例如将参数对象复制到真实数组或使用剩余参数。这个问题是关于 arguments 对象在 ES6 中是否应该是 iterable,可以在任何需要迭代的地方使用。

【问题讨论】:

这是一个已知的 FF 错误:The arguments object should support the ES6 @@iterator protocol @apsillers - 看起来已经编写了代码来修复它(上个月),并且正在审查和测试中。 【参考方案1】:

我想这是 FF 实现中的一个错误。

根据9.2.12 FunctionDeclarationInstantiation(func, argumentsList) 部分,

如果 argumentsObjectNeeded 为真,则

a) 如果 strict 为 true 或 simpleParameterList 为 false,则

==> i) 让 ao 为 CreateUnmappedArgumentsObject(argumentsList)。

b) 否则,

==> i) 注意映射的参数对象仅提供给没有剩余参数、任何参数默认值初始值设定项或任何解构参数的非严格函数。

==> ii) 让 ao 为 CreateMappedArgumentsObject(func, forms, argumentsList, env)。

CreateMappedArgumentsObjectCreateUnmappedArgumentsObject 都有

执行 DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor [[Value]]:%ArrayProto_values%, [[Writable]]: true, [[Enumerable] ]: false, [[Configurable]]: true)。

这意味着@@iterator 属性应该已经在arguments 对象上实际定义了。

【讨论】:

并且,为了明确地证明它没有被定义:(function(a) return arguments[Symbol.iterator] )(1) 在 FF 中产生 undefined,但在其他浏览器中是一个函数。 为了更好地了解现在要搜索的内容,我搜索了有关此问题的 Firefox 错误报告并在此处找到:The arguments object should support the ES6 @@iterator protocol。看起来它正在发布过程中(上个月为修复错误而编写的代码)。 感谢 ES6 规范中指向正确位置的指针。我期待arguments 对象的描述提到@@iterator,但那里根本没有提到。规范本身似乎比面向对象更具程序性,这似乎有点讽刺。 漏洞修复现已发布,可在 Firefox 46 中使用。

以上是关于arguments 对象是不是应该是 ES6 中的可迭代对象?的主要内容,如果未能解决你的问题,请参考以下文章

为啥函数的参数对象不是 Javascript 中的数组?

理解ES6中的Iterator

ES6-11学习笔记--箭头函数

浅谈js中arguments对象

es6 Array.from() 将类似数组的对象转化为数组

es6数组新特性