我正在阅读 ES6 的草稿,我在 Object.prototype.toString
中注意到了这个注释。部分:
Historically, this function was occasionally used to access the string value of the [[Class]] internal property that was used in previous editions of this specification as a nominal type tag for various built-in objects. This definition of toString preserves the ability to use it as a reliable test for those specific kinds of built-in objects but it does not provide a reliable type testing mechanism for other kinds of built-in or program defined objects.
来自阅读 this thread在 es-discuss 上,听起来像是
[[Class]]
正在替换为 [[NativeBrand]]
在 ES6 草案中,以便他们可以将其指定为不可扩展(那些至少是 Allen Wirfs-Brock's thoughts )。出于好奇,我在 FireFox 和 Chrome 中运行了一个快速测试(启用了实验性 JavaScript):
Object.prototype.toString.apply(new WeakMap());
=> '[object WeakMap]'
"WeakMap"
不是 [[NativeBrand]]
之一s 在 ES6 草案中指定。但是,此测试返回 "[object WeakMap]"
在两种浏览器上。所以我很困惑。我有几个问题。
1. Chrome 和 Firefox 的行为是否正确?
从阅读草稿的一种方式来看,听起来他们应该返回
[object Object]
(而且所有这些都是非常新的,所以在这些浏览器的 future 版本中看到这种变化我不会感到惊讶)。但是,我很难理解这部分草案的意图,尤其是有些地方带有"???"
.有没有更热心关注es-discuss的人有相关信息?或者谁能更好地理解草稿语言?
2.是否有替代
Object.prototype.toString
? 从上面引用的注释中,它听起来好像
Object.prototype.toString
由于遗留原因而保留,就好像现在应该使用一些新的东西来代替。尤其是读取"it does not provide a reliable type testing mechanism for other kinds of built-in ... objects"
的节点部分.这是否意味着无法使用此方法测试 future 的内置插件?让我们使用一个具体的例子。
如果我想确保从未知来源收到的对象是
String
对象(实际构造的 String
对象,不是原始字符串),我可以这样做:if (Object.prototype.toString.apply(unknownObject) != '[object String]')
throw new TypeError('String object expected.');
这让我知道
unknownObject
是 String
对象,无论它是在什么框架中构建的。我的问题是,这应该是我向 ES6 迈进的方法吗?或者有其他选择吗?类似
Object.getNativeBrandOf
?3. 自
[[NativeBrand]]
似乎它不会包括 future 类型的对象,如何测试这些对象? 这会起作用吗?
if (Object.prototype.toString.apply(unknownObject) != '[object Symbol]')
throw new TypeError('Symbol expected.');
...假设
Symbol
是私有(private)名称的最终名称。我应该使用这个吗?
if (Object.prototype.toString.apply(unknownObject) != '[object WeakMap]')
throw new TypeError('WeakMap expected.');
... 或者是其他东西?
我问的原因是我目前正在编写代码,希望能够在一两年内尽可能轻松地过渡到 ES6。如果有
Object.prototype.toString
的替代品,然后我可以将它填充并从那里继续。谢谢!更新
benvie 的回答为我提供了正确的术语来搜索和理解我的问题的答案。
我找到了 an email from Allen Wirfs-Brock on es-discuss关于这个问题。
这是我发现的,对于其他提出相同问题的人:
1. Chrome 和 Firefox 的行为是否正确?
是的,原因如下。
2.是否有替代
Object.prototype.toString
? 就像现在一样,在可能性的意义上会有一些“替代品”,但在替代品的意义上不会。
一种。 使用
@@toStringTag
象征。但是,我的理解是Object.prototype.toString
应该仍然可以使用。 @@toStringTag
提供允许扩展可以从 Object.prototype.toString
返回的结果。 .如果你有一个原型(prototype)想要添加你自己的字符串标签,你可以使用 @@toStringTag
将值设置为任何字符串。 Object.prototype.toString
将返回此值,除非此值是 ES5 内置函数之一,在这种情况下,字符串标记将带有“~”。湾在用户定义的对象上使用私有(private)符号。我读过一封电子邮件,宣传这是对用户定义的对象进行相同类型检查的最佳方式。但是,我不明白这如何真正解决问题,因为我无法理解它如何成为跨框架解决方案,并且它不允许您检查 ES6 内置程序。
因此,即使有一些替代方案,最好还是坚持使用
Object.prototype.toString
现在和 future ,有一个警告:它可以确保你有一个内置的 ES5,例如
String
,但确保你有一个内置的 ES6 并不是万无一失的,因为它们可以被 @@toStringTag
欺骗。 .我不确定为什么会这样,我可能会遗漏一些东西,或者它可能会随着规范的发展而改变。3. 自
[[NativeBrand]]
似乎它不会包括 future 类型的对象,如何测试这些对象? 如上所述,
Object.prototype.toString
仍然可以在 ES6 内置程序上使用,但它不是万无一失的,因为它可以被任何有权访问 @@toStringTag
的人欺骗。象征。然而,也许不应该有一个万无一失的方法,因为 Object.prototype.toString(weakmap) == '[object WeakMap]'
并不意味着 weakmap instanceof WeakMap
(它不应该!)。 weakmap
可能来自另一个框架,或者它可能是用户创建的类似弱图的对象。你唯一真正知道的是它报告在功能上等同于 WeakMap。它似乎引出了一个问题,为什么你不能有一个用户定义的对象,它报告在功能上等同于
String
或 Array
(没有前缀 "~"
)。
最佳答案
这目前是 ES6 规范中的一个移动目标。对于现有的对象集,出于各种原因(包括兼容性)维护现有机制。在最新的 ES6 规范中,published October 26th ,你可以找到一些关于 future 潜在方向的提示
15.4.6.2.4 ArrayIterator.prototype.@@toStringTag
The initial value of the @@toStringTag property is the string value "Array Iterator".15.14.5.13 Map.prototype.@@toStringTag
The initial value of the @@toStringTag property is the string value "Map".
您可以找到起源于此 in this thread 的原始讨论在 es-discus 上
关于javascript - 在 ES6 (ECMAScript 6) 中访问 [[NativeBrand]]/[[Class]],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13151643/