为啥 Boolean.prototype 又是一个布尔对象? (对于字符串和数字也是如此,但不是日期或正则表达式?)

Posted

技术标签:

【中文标题】为啥 Boolean.prototype 又是一个布尔对象? (对于字符串和数字也是如此,但不是日期或正则表达式?)【英文标题】:Why is Boolean.prototype a Boolean object again? (And same for String and Number, but not Date or RegExp?)为什么 Boolean.prototype 又是一个布尔对象? (对于字符串和数字也是如此,但不是日期或正则表达式?) 【发布时间】:2018-11-09 21:24:49 【问题描述】:

In ES5, Boolean.prototype 是一个布尔对象:

布尔原型对象本身就是一个布尔对象(其 [[Class]] 为“布尔”),其值为 false。

In ES6 / ES2015,不是:

布尔原型对象是一个普通对象。它不是布尔实例,也没有 [[BooleanData]] 内部槽。

In ES2016,又是:

布尔原型本身就是一个布尔对象;它有一个值为 false 的 [[BooleanData]] 内部槽。

(在 ES2017 中也是如此。)

Number.prototypeString.prototype 也是如此——而另一方面,Date.prototypeRegExp.prototype 在 ES5.1 中也开始是它们各自的 [[Class]] 实例,变成了普通的 @987654331 @ 在 ES6 中,此后一直保持这种状态。

在 ES2016 中的回归似乎不是 any tc39 proposal 的主题。

为什么在 ES6 中进行了这些更改,然后在 ES2016 中(仅)部分恢复了?

(这个问题不仅仅是为了学术/历史兴趣:我正在研究一种 javascript 方言,它不打算包含装箱的原始类型,但仍然需要 .prototype 对象来保存所有可以调用的方法在原始值上,虽然将 .prototype 对象特例化为它们各自 [[Class]] 的唯一实例是可行的,但我想了解为什么这可能是可取的。)

【问题讨论】:

可能的后续问题,如果恢复的原因是“网络兼容性”:为什么没有在附件 B 中完成? ES2016 也说“布尔原型对象是一个普通对象”。似乎几乎相互矛盾?但我认为这只是意味着Boolean.prototype 是一个普通对象+[[BooleanData]] 插槽。规范并没有真正详细说明这些对象是如何创建的:ecma-international.org/ecma-262/7.0/…。 @FelixKling:我认为“普通对象”的意思是,它具有 §9.1 中指定的所有普通内部对象方法,而不是 String 对象,后者具有替代§9.4.3 中给出的定义。所以,是的:普通对象 + [[BooleanData]]。 【参考方案1】:

我还没有找到完整的解释为什么这些对象在 ES6 中变成了普通的Objects,但是回滚的原因似乎是因为它导致了意想不到的问题:来自"Number.prototype not being an instance breaks the web, too" on esdiscuss.org:

V8 昨天刚刚对 Canary 进行了一项更改,它实现了 Number.prototype(和 Boolean.prototype)作为普通对象的新 ES6 语义。不幸的是,这似乎破坏了网络。特别是 jsfiddle.net/#run 现在无法加载。

我在该页面上看到的是一个 TypeError “Number.prototype.valueOf is not generic” 被抛出在这个函数中(可能是 moo 工具的一部分):

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

在 Number.prototype 上调用之后。

AFAICS,只剩下一个选择:退出此规范更改。

——安德烈亚斯·罗斯伯格

而且似乎回滚不适用于Date.prototypeRegExp.prototype,因为它们带有可变状态:

从安全角度来看,重要的不恢复是那些携带未被 Object.freeze 锁定的可变状态的状态。在 ES5 中,这只是 Date.prototype。在 ES6 中的 ES5 内置函数中,由于 RegExp.prototype.compile,这现在包括 RegExp.prototype。

——马克·S·米勒

【讨论】:

以上是关于为啥 Boolean.prototype 又是一个布尔对象? (对于字符串和数字也是如此,但不是日期或正则表达式?)的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 JavaScript 中函数既是构造函数又是对象?

TS中的String " vs char ',为啥这又是一个问题

为啥 __builtins__ 既是模块又是字典

机器学习为啥需要训练,训练出来的模型具体又是啥

为啥我的VS2005用几天后就老是出现加载项目失败啊.我把系统还原了.从新安装用几天后又是这样.

我想知道为啥我的cadence在win7 32位安装以后打开出现这个错误,我查看license又是正常安装的,