Why is Boolean.prototype a Boolean object again? (And same for String and Number, but not Date or RegExp?)

时光怂恿深爱的人放手 提交于 2021-02-08 05:31:10

问题


In ES5, Boolean.prototype is a Boolean object:

The Boolean prototype object is itself a Boolean object (its [[Class]] is "Boolean") whose value is false.

In ES6 / ES2015, it isn't:

The Boolean prototype object is an ordinary object. It is not a Boolean instance and does not have a [[BooleanData]] internal slot.

In ES2016, it is once again:

The Boolean prototype is itself a Boolean object; it has a [[BooleanData]] internal slot with the value false.

(and it remains so in ES2017 as well.)

The same is true for Number.prototype and String.prototype—while on the other hand Date.prototype and RegExp.prototype also began as instances of their respective [[Class]]es in ES5.1, became plain Objects in ES6 and have remained that way since.

The reversion, in ES2016, does not appear to have been the subject of any tc39 proposal.

Why were these changes made in ES6, and then (only) partially reverted in ES2016?

(This question is not just for academic/historical interest: I am working on a JavaScript dialect that is intended not to include the boxed primitive types but which still requires the .prototype objects to hold all the methods that can be invoked on primitive values, and while it's feasible to special-case the .prototype objects as being the only instances of their respective [[Class]]es, I'd like to understand why that might be desirable.)


回答1:


I have not been able to find an full explanation of why these objects became plain Objects in ES6, but the reason for the rollback appears to be because it caused unexpected problems: from "Number.prototype not being an instance breaks the web, too" on esdiscuss.org:

V8 just rolled a change into Canary yesterday that implements the new ES6 semantics for Number.prototype (and Boolean.prototype) being ordinary objects. Unfortunately, that seems to break the web. In particular jsfiddle.net/#run fails to load now.

What I see happening on that page is a TypeError "Number.prototype.valueOf is not generic" being thrown in this function (probably part of moo tools):

Number.prototype.$family = function(){
return isFinite(this) ? 'number' : 'null';
}.hide();

after being invoked on Number.prototype.

AFAICS, that leaves only one option: backing out of this spec change.

–Andreas Rossberg

And it seems that the rollback was not applied to Date.prototype and RegExp.prototype because they carry mutable state:

From a security pov, the important ones not to revert are those carrying mutable state not locked down by Object.freeze. In ES5 this was only Date.prototype. Of the ES5 builtins in ES6, this now includes RegExp.prototype because of RegExp.prototype.compile.

—Mark S. Miller



来源:https://stackoverflow.com/questions/50614565/why-is-boolean-prototype-a-boolean-object-again-and-same-for-string-and-number

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!