草庐IT

javascript - 在 ES6 (ECMAScript 6) 中访问 [[NativeBrand]]/[[Class]]

coder 2024-07-26 原文

我正在阅读 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.');

这让我知道 unknownObjectString对象,无论它是在什么框架中构建的。

我的问题是,这应该是我向 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。

它似乎引出了一个问题,为什么你不能有一个用户定义的对象,它报告在功能上等同于 StringArray (没有前缀 "~" )。

最佳答案

这目前是 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/

有关javascript - 在 ES6 (ECMAScript 6) 中访问 [[NativeBrand]]/[[Class]]的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  3. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  4. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  5. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  6. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  7. ruby - 从外部访问类的实例变量 - 2

    我理解(我认为)Ruby中类变量和类的实例变量之间的区别。我想知道如何从该类外部访问该类的实例变量。从内部(即在类方法中而不是实例方法中),它可以直接访问,但是从外部,有没有办法做MyClass.class.[@$#]variablename?我没有任何具体原因要这样做,只是学习Ruby并想知道是否可行。 最佳答案 classMyClass@my_class_instance_var="foo"class上述yield:>>foo我相信Arkku演示了如何从类外部访问类变量(@@),而不是类实例变量(@)。我从这篇文章中提取了上述内

  8. ruby-on-rails - 使用 HTTP.get_response 检索 Facebook 访问 token 时出现 Rails EOF 错误 - 2

    我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token

  9. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐