翻译本文的目的是尝试给出 ECMAScript 规范中核心术语的译法,供同好品评。
在这篇文章里,我们会从规范中找一个简单的功能,借以理解规范中的符号。开始吧!
即便你懂 JavaScript,阅读其规范也会让人畏缩。
让我们从一个具体的例子开始,然后通过规范去理解它。下面的代码演示了 Object.prototype.hasOwnProperty
的用法:
const o = { foo: 1 };
o.hasOwnProperty('foo'); // true
o.hasOwnProperty('bar'); // false
o
并没有一个叫hasOwnProperty
的属性,因此要沿原型链向上查找。于是,在o
的原型Object.prototype
上找到了它。
为描述Object.prototype.property
的工作原理,规范使用了类似伪代码的说明:
Object.prototype.hasOwnProperty(V)
在以参数 V 调用hasOwnProperty
方法时,将执行以下步骤: 1. 令P
为 ? ToPropertyKey(V); 2. 令O
为 ? ToObject(this值); 3. 返回? HasOwnProperty(O, P)
。
以及
HasOwnProperty(O, P)
抽象操作HasOwnProperty
用于确定对象是否有一个以指定属性为键的自有属性。返回布尔值。这个操作以参数O
和P
调用,其中O
是对象,P
是属性键。这个抽象操作执行以下步骤。 1. 断言:Type(O)
为Object
; 2. 断言:IsPropertyKey(P)
为true
; 3. 令desc
为? O.[[GetOwnProperty]](P)
; 4. 若desc
为undefined
,返回false
; 5. 返回true
。
什么是“抽象操作”?[[]]
里面的东西表示什么?为什么把一个?
放在函数前面?“断言”又是什么意思?
规范使用了undefined
、true
和false
这些我们在 JavaScript 中已经知道的值。这些都是语言值[1],即规范中定义的语言类型的值。
规范内部也使用语言值,比如某个内部数据类型的字段可能包含true
或false
。相对而言,JavaScript 引擎通常不会在内部使用语言值。例如,如果 JavaScript 引擎是用 C++写的,那通常会使用 C++的true
和false
,而这并不是 JavaScript 语言值true
和false
的内部表示。
除了语言类型,规范也有自己的规范类型[2]。规范类型是只存在于规范中的类型,JavaScript 语言中不存在。JavaScript 引擎不需要(但完全可以)实现它们。本文将介绍规范类型记录(Record)及其子类型完成记录(Completion Record)。
抽象操作[3]是 ECMAScript 规范定义的函数,定义它们的目的是为了让规范更简洁。JavaScript 引擎不必在内部实现这些函数。这些函数不能直接在 JavaScript 中调用。
内部栏位(slot)和内部方法[4]包含在[[]]
中。
内部栏位是 JavaScript 对象或规范类型的数据成员,用于存储对象的状态。内部方法是 JavaScript 对象的内部成员函数。
比如,每个 JavaScript 对象都有一个内部栏位[[Prototype]]
和一个内部方法[[GetOwnProperty]]
。
内部栏位和内部方法不能在 JavaScript 中使用。换句话说,不能访问o.[[Prototype]]
或调用o.[[GetOwnProperty]]()
。JavaScript引擎可以为了内部使用实现它们,但不是必需的。
有时候内部方法也会委托到名字类似的抽象操作,比如普通对象(ordinary object)的[[GetOwnProperty]]
:
[[GetOwnProperty]](p)
在以属性键 P 调用内部方法[[GetOwnProperty]]
时,将执行以下步骤: 1. 返回<span style="font-variant-ligatures: normal;orphans: 2;widows: 2;text-decoration-thickness: initial;">! OrdinaryGetOwnProperty(O, P)
。
(下一篇文章会介绍这里的叹号表示什么意思。)
OrdinaryGetOwnProperty
不是内部方法,因为它不与任何对象关联,而是以接收参数的形式取得要操作的对象。
OrdinaryGetOwnProperty
前面的“ordinary”(普通)表示它只操作普通对象。ECMAScript 对象要么是普通对象(ordinary),要么是异质对象(exotic)。普通对象必须具有一组被称为基本内部方法(essential internal methods)的方法所定义的默认行为。如果某个对象修改了默认行为(即覆盖或重写了一个或多个基本内部方法。——译者注),那它就是异质对象。
大家最熟悉的Array
就是异质对象,因为其length
属性的行为与默认行为不同:设置数组的length
属性可能会从数组中删除元素。
这里给出了所有基本内部方法[5](普通对象 11 个,函数对象 2 个。——译者注)。
前面例子中出现的问号和叹号表示什么意思?要理解它们,需要先理解完成记录[6](Completion Record)!
完成记录是一种规范类型(只在规范中使用)。JavaScript 引擎不需要实现对应的内部数据类型。
完成记录是一种记录类型(Record),而记录具有一组固定的命名字段。完成记录具有以下 3 个字段。
所有抽象操作都会隐式返回一个完成记录。即便一个抽象操作看起来返回简单类型(如 Boolean)的值,这个值也会被隐式包装在一个normal
类型(正常完成)的完成记录中返回(参见隐式完成值[7])。
注 1:规范本身在这方面也不是完全一致。有一些辅助函数会返回裸值,而这些值将直接被使用,无需从完成记录中提取。不过这种情况在上下文中通常能够一目了然。 注 2:规范编辑也在致力于更显式地处理完成记录。
如果某个算法抛出异常,则意味着返回的完成记录的[[Type]]
为throw
,[[Value]]
为异常对象。我们这里不讨论break
、continue
和return
类型(规范中没有相应的例子,因为这几种类型不能跨函数。——译者注)。
ReturnIfAbrupt(argument)表示执行如下步骤:
1. 若
argument
为硬性完成,返回argument
; 2. 设argument
为argument.[[Value]]
。
换句话说,对于完成记录,如果是硬性完成,则立即返回;如果是正常完成,则提取完成记录的值。
ReturnIfAbrupt
看起来虽然像函数调用,但它不是。ReturnIfAbrup
会导致它所在位置的函数返回,而不是ReturnIfAbrupt
本身返回。ReturnIfAbrupt
有点像 C 语言中的宏。
ReturnIfAbrupt
可以这样用:
1.令
obj
为Foo()
;(obj
是一个完成记录。) 2.ReturnIfAbrupt(obj)
; 3.Bar(obj)
。(如果到了这一步,obj
已经变成了从完成记录中提取出来的值。)
现在该说到问号[8]了:? Foo()
等价于ReturnIfAbrupt(Foo())
。显然,使用简写(?
)可以省去每次都明确写出错误处理代码的麻烦。
类似地,“令val
为 ! Foo()”等价于:
1. 令
val
为Foo()
;(val
是一个完成记录。) 2. 断言:val
非硬性完成; 3. 设val
为val.[[Value]]
。
(换句话说,叹号表示从正常完成记录中提取值。——译者注 )
知道了这些之后,就可以把前面的Object.prototype.hasOwnProperty
以完整但冗余的形式重写如下:
Object.prototype.hasOwnProperty(V) 1. 令
P
为ToPropertyKey(V)
; 2. 若P
为硬性完成,返回P
; 3. 设P
为P.[[Value]]
; 4. 令O
为ToObject(this值)
; 5. 若O
为硬性完成,返回O
; 6. 设O
为O.[[Value]]
; 7. 令temp
为HasOwnProperty(O, P)
; 8. 若temp
为硬性完成,返回temp
; 9. 设temp
为temp.[[Value]]
; 10. 返回NormalCompletion(temp)
。
把抽象操作HasOwnProperty()
重写如下:
HasOwnProperty(O, P) 1. 断言:
Type(O)
为Object
; 2. 断言:IsPropertyKey(P)
为true
; 3. 令desc
为O.[[GetOwnProperty]](P)
; 4. 若desc
为硬性完成,返回desc
; 5. 设desc
为desc.[[Value]]
; 6. 若desc
为undefined
,返回NormalCompletion(false)
; 7. 返回NormalCompletion(true)
。
进而把内部方法O.[[GetOwnProperty]]
以不带叹号的形式重写如下:
O.[[GetOwnProperty]] 1. 令
temp
为OrdinaryGetOwnProperty(O, P)
; 2. 断言:temp
非硬性完成; 3. 令temp
为temp.[[Value]]
; 4. 返回NormalCompletion(temp)
;
这里假设temp
是个新的临时变量,不与任何其他变量冲突。
这里也用到了前面说的当返回语句返回非完成记录时,实际上返回值将被隐式包装在一个NormalCompletion
中。
扩展学习:返回? Foo()
规范中使用“返回? Foo()
”这种写法,为什么还要加个问号呢?
“返回? Foo()
”扩展后是:
1. 令
temp
为Foo()
; 2. 若temp
为硬性完成,返回temp
; 3. 设temp
为temp.[[Value]]
; 4. 返回NormalCompletion(temp)
。
这跟“返回Foo()
”没有区别:即无论硬性完成还是正常完成,行为都一样。
写成“返回 ? Foo() ”仅仅是出于编辑方便的考虑,为了更明确地表示返回的Foo()
是一个完成记录。
规范中的“断言”提示算法中不变的条件。添加这些“断言”是为了明确起见,不要求实现。换句话说,实现不需要检查这些条件。
抽象操作也会委托给其他抽象操作(见下图),但根据本文的介绍,大家应该能推断出这些操作最终干了什么事。这里面会碰到属性描述符(Property Descriptor),也是一种规范类型。
我们通过规范看到了一个简单的方法Object.prototype.hasOwnProperty
和它调用的抽象操作,知道了?和!与错误处理有关,也了解了语言类型、规范类型、内部栏位和内部方法。
原文链接[9]
[1] 语言值: https://tc39.es/ecma262/#sec-ecmascript-language-types
[2] 规范类型: https://tc39.es/ecma262/#sec-ecmascript-specification-types
[3] 抽象操作: https://tc39.es/ecma262/#sec-abstract-operations
[4] 内部栏位(slot)和内部方法: https://tc39.es/ecma262/#sec-object-internal-methods-and-internal-slots
[5] 基本内部方法: https://tc39.es/ecma262/#table-5
[6] 完成记录: https://tc39.es/ecma262/#sec-completion-record-specification-type
[7] 隐式完成值: https://tc39.es/ecma262/#sec-implicit-completion-values
[8] 问号: https://tc39.es/ecma262/#sec-returnifabrupt-shorthands
[9] 原文链接: https://v8.dev/blog/understanding-ecmascript-part-1
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/scA3PepT_JcNk0U4EXbHwA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。