In ES5,Boolean.prototype
是一个布尔对象:
布尔原型对象本身就是一个布尔对象(它的[[Class]]是"布尔"),其值为false。
In ES6 / ES2015,它不是:
布尔原型对象是普通对象。它不是布尔实例,也没有[[BooleanData]]内部插槽。
In ES2016,又一次:
布尔原型本身就是一个布尔对象;它有一个[[BooleanData]]内部插槽,值为false。
(在ES2017中也是如此。)
Number.prototype
和String.prototype
也是如此 - 而另一方面,Date.prototype
和RegExp.prototype
也是作为各自[[Class]] es的实例开始的ES5.1在ES6中变得简单Objects
并且自那以后一直保持这种状态。
在ES2016中的回归似乎不是any tc39 proposal的主题。
为什么在ES6中进行了这些更改,然后(仅)在ES2016中进行了部分还原?
(这个问题不仅仅是出于学术/历史的兴趣:我正在研究一种JavaScript方言,该方言不包括盒装基元类型,但仍需要.prototype
个对象来保存所有可以使用的方法可以在原始值上调用,虽然将.prototype
个对象作为其各自[[Class]] es的唯一实例进行特殊处理是可行的,但我想了解为什么可能是可取的。)
答案 0 :(得分:0)
我无法在ES6中找到这些对象变为普通Object
的原因的完整解释,但回滚的原因似乎是因为它导致了意外问题:来自"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上调用后Number.prototype.$family = function(){ return isFinite(this) ? 'number' : 'null'; }.hide();
。
AFAICS,只留下一个选项:退出此规范更改。
-Andreas Rossberg
似乎回滚未应用于Date.prototype
和RegExp.prototype
,因为它们带有可变状态:
从安全性pov中,不回复的重要部分是那些不被Object.freeze锁定的可变状态。在ES5中,这只是Date.prototype。在ES6内置的ES5中,由于RegExp.prototype.compile,现在包含RegExp.prototype。
-Mark S. Miller