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)。
CreateMappedArgumentsObject
和 CreateUnmappedArgumentsObject
都有
执行 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 中的可迭代对象?的主要内容,如果未能解决你的问题,请参考以下文章