为什么在ES2015中将Object.keys更改为将原语强制转换为对象?

phi*_*raj 6 javascript ecmascript-6

有谁知道更改的原因,从传递基元时引发错误Object.keys到静默地将基元强制给对象并返回结果,是造成更改的原因?

我不确定有人会Object.keys('abc')返回[0, 1, 2],而且似乎违反了“不要破坏网络”的主要指令。如果某些网站的代码Object.keys在try / catch中包装了对的调用,以处理错误地传递原语的调用者?

这就是为什么我认为变革背后必须有强有力的理由。如果有人在此方面有一些信息,我将非常感兴趣。

aps*_*ers 1

我在esdiscuss上找不到任何关于这个决定的提及,所以我只能提供我自己的观点。

正如评论者指出的那样,这是 ES 2015 更大趋势的一部分,即更广泛地允许非对象输入。在 ES 2015 规范中,短语“在以前的版本中,非对象参数总是导致TypeError抛出 a”,出现在Object.

首先,这种变化使 的行为Object.keys与循环的行为保持一致for-in,循环始终能够对基元进行操作。考虑到规范已经要求Object.keys和之间的顺序匹配for-in,要求相同的有效操作数集似乎并不奇怪。

这一更改似乎对现有代码几乎无害,同时大大降低了Object.keys. 即使在 try-catch 的情况下,也很难想象成功Object.keys执行会导致实际问题的情况。我可以很容易地想象这样的代码:

try {
    var keys = Object.keys(input);
} catch {
    // oops, input was a primitive; call `new [Constructor]` to wrap it
    var keys = Object.keys(
        new input.constructor(input)
    );
}
Run Code Online (Sandbox Code Playgroud)

Object.keys但是,当没有错误时,这不会中断;成功的Object.keys调用会使catch代码过时。

当然,在某个地方可能存在这样的代码:

try {
    var keys = Object.keys(input);
} catch {
    // oops, input was a primitive; that unlocks the secret prize
    giveUserAFreePuppy();
}
Run Code Online (Sandbox Code Playgroud)

基本上,我想说的是,通过一个非常愚蠢的例子,跳过一个catch块对于某些代码的操作来说确实是有问题的情况看起来是如此牵强,以至于破坏这样的代码似乎是一个很小的代价获得不那么脆弱的Object.keys功能。