【问题标题】: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,可以在任何需要迭代的地方使用。

【问题讨论】:

标签: javascript ecmascript-6 iterable


【解决方案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 中使用。
猜你喜欢
  • 2012-11-11
  • 1970-01-01
  • 2016-02-07
  • 2017-05-02
  • 1970-01-01
  • 1970-01-01
  • 2017-12-16
  • 1970-01-01
  • 2011-10-05
相关资源
最近更新 更多