最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • [译]理解 ECMAScript 规范(1)

    正文概述 掘金(字节前端)   2021-03-28   447

    译者: 李松峰

    在这篇文章里,我们会从规范中找一个简单的功能,借以理解规范中的符号。开始吧!

    前言

    即便你懂 JavaScript,阅读其规范也会让人畏缩。

    让我们从一个具体的例子开始,然后通过规范去理解它。下面的代码演示了 Object.prototype.hasOwnProperty 的用法:

    const o = { foo: 1 };
    o.hasOwnProperty('foo'); // true
    o.hasOwnProperty('bar'); // false
    

    o并没有一个叫hasOwnProperty的属性,因此要沿原型链向上查找。于是,在o 的原型Object.prototype上找到了它。

    为描述Object.prototype.property的工作原理,规范使用了类似伪代码的说明:

    以及

    什么是“抽象操作”?[[]]里面的东西表示什么?为什么把一个?放在函数前面?“断言”又是什么意思?

    语言类型与规范类型

    规范使用了undefinedtruefalse这些我们在 JavaScript 中已经知道的值。这些都是语言值,即规范中定义的语言类型的值。

    规范内部也使用语言值,比如某个内部数据类型的字段可能包含truefalse。相对而言,JavaScript 引擎通常不会在内部使用语言值。例如,如果 JavaScript 引擎是用 C++写的,那通常会使用 C++的truefalse,而这并不是 JavaScript 语言值truefalse的内部表示。

    除了语言类型,规范也有自己的规范类型。规范类型是只存在于规范中的类型,JavaScript 语言中不存在。JavaScript 引擎不需要(但完全可以)实现它们。本文将介绍规范类型记录(Record)及其子类型完成记录(Completion Record)。

    抽象操作

    抽象操作是 ECMAScript 规范定义的函数,定义它们的目的是为了让规范更简洁。JavaScript 引擎不必在内部实现这些函数。这些函数不能直接在 JavaScript 中调用。

    内部栏位及内部方法

    内部栏位(slot)和内部方法包含在[[]]中。

    内部栏位是 JavaScript 对象或规范类型的数据成员,用于存储对象的状态。内部方法是 JavaScript 对象的内部成员函数。

    比如,每个 JavaScript 对象都有一个内部栏位[[Prototype]]和一个内部方法[[GetOwnProperty]]

    内部栏位和内部方法不能在 JavaScript 中使用。换句话说,不能访问o.[[Prototype]]或调用o.[[GetOwnProperty]]()。JavaScript引擎可以为了内部使用实现它们,但不是必需的。

    有时候内部方法也会委托到名字类似的抽象操作,比如普通对象(ordinary object)的[[GetOwnProperty]]

    (下一篇文章会介绍这里的叹号表示什么意思。)

    OrdinaryGetOwnProperty不是内部方法,因为它不与任何对象关联,而是以接收参数的形式取得要操作的对象。

    OrdinaryGetOwnProperty前面的“ordinary”(普通)表示它只操作普通对象。ECMAScript 对象要么是普通对象(ordinary),要么是异质对象(exotic)。普通对象必须具有一组被称为基本内部方法(essential internal methods)的方法所定义的默认行为。如果某个对象修改了默认行为(即覆盖或重写了一个或多个基本内部方法。——译者注),那它就是异质对象。

    大家最熟悉的Array就是异质对象,因为其length属性的行为与默认行为不同:设置数组的length属性可能会从数组中删除元素。

    这里给出了所有基本内部方法(普通对象 11 个,函数对象 2 个。——译者注)。

    完成记录

    前面例子中出现的问号和叹号表示什么意思?要理解它们,需要先理解完成记录(Completion Record)!

    完成记录是一种规范类型(只在规范中使用)。JavaScript 引擎不需要实现对应的内部数据类型。

    完成记录是一种记录类型(Record),而记录具有一组固定的命名字段。完成记录具有以下 3 个字段。

    [译]理解 ECMAScript 规范(1)

    所有抽象操作都会隐式返回一个完成记录。即便一个抽象操作看起来返回简单类型(如 Boolean)的值,这个值也会被隐式包装在一个normal类型(正常完成)的完成记录中返回(参见隐式完成值)。

    如果某个算法抛出异常,则意味着返回的完成记录的[[Type]]throw[[Value]]为异常对象。我们这里不讨论breakcontinuereturn类型(规范中没有相应的例子,因为这几种类型不能跨函数。——译者注)。

    ReturnIfAbrupt(argument) 表示执行如下步骤:

    换句话说,对于完成记录,如果是突然完成,则立即返回;如果是正常完成,则提取完成记录的值。

    ReturnIfAbrupt看起来虽然像函数调用,但它不是。ReturnIfAbrup会导致它所在位置的函数返回,而不是ReturnIfAbrupt本身返回。ReturnIfAbrupt有点像 C 语言中的宏。

    ReturnIfAbrupt可以这样用:

    现在该说到问号了:? Foo()等价于ReturnIfAbrupt(Foo())。显然,使用简写(?)可以省去每次都明确写出错误处理代码的麻烦。

    类似地,“令val! Foo()”等价于:

    (换句话说,叹号表示从正常完成记录中提取值。——译者注 )

    知道了这些之后,就可以把前面的Object.prototype.hasOwnProperty以完整但冗余的形式重写如下:

    把抽象操作HasOwnProperty()重写如下:

    1.断言:Type(O)Object
    2.断言:IsPropertyKey(P)true
    3.令descO.[[GetOwnProperty]](p)
    4.若desc为突然完成,返回desc
    5.设descdesc.[[Value]]
    6.若descundefined,返回NormalCompletion(false)
    7.返回NormalCompletion(true)

    进而把内部方法O.[[GetOwnProperty]]以不带叹号的形式重写如下:

    这里假设temp是个新的临时变量,不与任何其他变量冲突。

    这里也用到了前面说的当返回语句返回非完成记录时,实际上返回值将被隐式包装在一个NormalCompletion中。

    扩展学习:返回? Foo()

    规范中使用“返回? Foo()”这种写法,为什么还要加个问号呢?

    “返回? Foo()”扩展后是:

    这跟“返回Foo()”完全一样:如果是突然完成,返回突然完成记录;如果是正常完成,返回正常完成记录。

    写成“返回Foo()”只是为了编辑方便,为了更明确地表示返回的Foo()是一个完成记录。

    断言

    规范中的“断言”提示算法中不变的条件。添加这些“断言”是为了明确起见,不要求实现。换句话说,实现不需要检查这些条件。

    挑战

    抽象操作也会委托给其他抽象操作(见下图),但根据本文的介绍,大家应该能推断出这些操作最终干了什么事。这里面会碰到属性描述符(Property Descriptor),也是一种规范类型。

    [译]理解 ECMAScript 规范(1)

    小结

    我们通过规范看到了一个简单的方法Object.prototype.hasOwnProperty和它调用的抽象操作,知道了?!与错误处理有关,也了解了语言类型、规范类型、内部栏位和内部方法。

    原文链接

    欢迎关注「 字节前端 ByteFE 」简历投递联系邮箱「 tech@bytedance.com 」


    下载网 » [译]理解 ECMAScript 规范(1)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元