摘要:标准对象,语义由本规范定义的对象。三个冒号作为分隔符分割数字字符串文法的产生式。所有因为带来的问题,基本上是占着茅坑不拉屎的行为导致。以数组测试操作为例,标准中的描述如下相对于来说,规范中增加了对的处理。
前言
本文是对《ECMAScript 2018 Language Specification》的解读。
本文是对标准的概述性导读,不是对 ES2018特性的详细描述,也不会针对某个技术点进行详细展开,但是会附上相关文章外链。
整个文档有引言+27个章节+7篇附录,大概五六百页的样子。
引言和前面3章部分,都是在讲规格本身,跟JS语言本身无关。内容很少,可以快速过一遍。
Introduction 部分 介绍了语言历史和标准化历程;
前3章 Scope、Conformance、Normative References 主要介绍了文档的范围、一致性和参考文献。所谓一致性,实际上是标准实现的一致性,任何实现ECMAScript 标准的语言,都必须完全实现文档中描述的语法和语义,并且可以有规格之外的自定义程序语法。
语言概述第4章 Overview 是对语言的整体介绍。涵盖了Web脚本语言环境、ES基本概念和专业术语,以及严格模式的简单介绍。这里跟大家分享几个有意思的点。
奇葩的面向对象机制ECMAScript is an object-oriented programming language for performing computations and manipulating computational objects within a host environment.
ES是一门面向对象的语言,这是官方描述!(这有什么奇怪的啊,大家都知道啊)但是ES的面向对象设计机制却是与众不同,大有学问(这有什么啊,不就原型链嘛)。我们多少都了解一些,但要完全讲清楚,恐怕专门开一篇博客也不够。
但我还是尝试专门写了一篇:《如何优雅的解读JS的面向对象机制》。
脚本语言的逆袭ECMAScript was originally designed to be used as a scripting language, but has become widely used as a general-purpose programming language.
这个就有点屌了,ES最初是被拿来当Web脚本语言用的,但现在已经成了时下最流行的通用编程语言之一。此中缘由大家应该也很清楚,不多说,只是抒发一下感慨:Always bet on JS可不是乱说的。
有关对象的描述本章还列举出了JS中的专业名词及解释,比如类型、原始值、对象、构造器、原型......等概念。有意思的是标准中关于对象的描述在ES5里面有三种:
native object(原生对象),指语义完全由规范定义并且不掺杂任何宿主环境定义的的对象;
build-in object(内置对象),由ECMA实现提供,程序执行时就存在的对象。所有内置对象都是原生对象。
host object(宿主对象),由执行环境提供,比如浏览器的window对象和history对象。JS里的对象不是原生对象就是宿主对象。
但是在ES6之后就改成了四种:
ordinary object:普通对象,只要具备了对象的所有基本内置方法就可以了。
exotic object:外来对象,如果不具备标准对象所有的基本内置方法,就是外来对象。JS里的对象不是普通对象就是外来对象。
standard object:标准对象,语义由本规范定义的对象。
built-in object:内置对象,跟ES5中描述一样。
对比来看,前者是以宿主环境为划分条件,后者则是以对象的基本内置方法。ES6之后其实划分的更细了。
记法约定第5章 Notational Conventions 详细介绍了规范描述中用到的一些句法、词法以及算法约定等内容,如果要看懂后面的有关语法行为,函数实现的详细描述,就得看懂这章,看完之后你甚至可以照着标准实现一遍。
这章涉及大量编译基本知识,还是强烈建议花些时间看下,不然后面可能没法继续。你需要知道以下概念:
上下文无关文法作为ECMAScript规格文档,自然需要用一种专业的方式来描述这门语言,这种专业的描述语言的方法,就是所谓的文法(文法由若干产生式组成)。而上下文无关的意思,就是所有产生式的左边只有一个非终结符,因为只有这样,产生式右边的串才能规约到左边的非终结符,否则就是上下文相关。大部分编程语言都是上下文无关文法,ECMAScript也不例外。
词法、正则文法、数字字符串文法和句法约定一个冒号“:”作为分隔符分割句法的产生式。两个冒号“::”作为分隔符分割词法和正则的文法产生式。词法和正则的文法共享某些产生式。三个冒号“:::”作为分隔符分割数字字符串文法的产生式。然后列举了各种句法,文法标记,总之很多概念,此处不展开。
内部机制第6到8章详细描述了语言运行的内部机制,从宏观上对ES进行描述,包括数据类型和值,语言内部的抽象操作,以及代码执行的上下文相关知识。
类型ES中的类型可细分为ES语言类型和规范类型,语言类型对应的是程序中直接被操作的值的类型,包括Undefined,Null,Boolean,Number,String,Object,Symbol。理解类型,是理解这门语言的基础。
首先是Undefind和Null,二者区别可参考 undefined与null的区别 - 阮一峰。在一门编程语言中对于“空”的描述用到了两种基本类型,估计只有JavaScript了。其实一开始只有null,后来为了解决类型转换和错误处理问题引入了undefined。
undefined 表示此处应该有个值,但是这个值还没给出来,其实就是占了个坑,这个坑是语言内部实现帮你做的,你不用管。null 才是真正意义上的空值,表示对象世界中的“无”。正所谓道生一,一生二,二生三,三生万物。JS中万物皆对象,所有对象的原型链都可以上溯到唯一的Object,而Object的原型,正是万物之始源,混沌之道null。所以JS中null的意义远超其他编程语言,这正是让JS的面向对象思想与道家哲学完美契合的重要一笔。
所以个人理解,Undefined虽然作为基本类型,解决的却是语言内部处理问题,所以永远不要在代码中主动出现,要在语义上处理空就用null。所有因为undefined带来的问题,基本上是占着茅坑不拉屎的行为导致。所以google在Dart中就只有null,而没有undefined,因为undefined解决的问题完全可以在语言内部解决,没必要暴露给用户。
Boolean和Symbol没啥好说的,数值的设计也是从简,只有一个Number类型。有意思的是String,官方对于String类型的描述:
The String type is the set of all ordered sequences of zero or more 16-bit unsigned integer values (“elements”) up to a maximum length of 2e53 - 1 elements.
翻译过来就是指所有有限的零个或多个16位无符号整数值的有序序列(共计2e53 - 1个元素)。这个2e53 - 1是怎么来的呢,按照16位无符号整数值计算的话?
更有意思的是,String中的每一个字符都被视为独立的UTF-16代码单元,即占2个字节,作用在字符串上的所有操作都视它们为无差别的16位无符号整数(这里的UTF-16,其实是指内部实现,计算机内存中都是基于unicode编码的,只是在存储或读取时会进行UTF-8或者其他编码类型转换)。但是UTF-16却有两种长度的字符,U+0000到U+FFFF之间的字符占2个字节,U+10000到U+10FFFF之间的字符占4字节。对于4字节的字符ES是无法准确处理的,需要自己去根据编码值情况判断,这也是一大坑爹之处。
对此,我也专门写了一篇:《深入理解JavaScript中的String类型-未发布》。
除了以上语言类型,整个规范中还有用于描述这门语言的规范类型,规范类型的值是规范自己造的,有的还是ES表达式计算的中间结果,所以没必要对应到特定的语言类型上。若非特别说明,ES中的类型通常指语言类型。
操作摘要类型之间会涉及到各种运算,这就会涉及到各种操作运算。比如类型转换涉及到的内部机制和算法流程,7.1 Type Conversion 都有详细说明。7.2 Testing and Comparison Operations 讲了测试和比较操作,比如测试一个对象是否是数组,是否数字,是否构造函数,以及 == 和 === 的定义等等。以数组测试操作isArray(argument)为例,标准中的描述如下:
1. If Type(argument) is not Object, return false. 2. If argument is an Array exotic object, return true. 3. If argument is a Proxy exotic object, then a. If argument.[[ProxyHandler]] is null, throw a TypeError exception. b. Let target be argument.[[ProxyTarget]]. c. Return ? IsArray(target). 4. Return false.
相对于ES5来说,规范中增加了对Proxy的处理。我们再看 underscope v1.8.3 源码中对isArray的实现:
_.isArray = Array.isArray || function(obj) { return toString.call(obj) === "[object Array]"; }
相对于ES5来说,规范中增加了对Proxy的处理,目前来看这是引擎内部处理的,对现在很多检测数组的方法并不影响。
语言实现细节这是个大坑,还是附上ES2018正式版规范地址吧:
https://www.ecma-internationa...
如果想快速了解一下新特性,可以看这里:
https://medium.com/front-end-...
具体有哪些 finished proposals 可以参考 tc39 的 GitHub。
如何优雅的阅读ECMA标准由于目前使用最为广泛的还是ECMA 5.1版本,所以在阅读ES2018之前,建议先把5.1的标准看一遍,方便对比。好在W3C中文站有5.1的100%翻译版本:
ES5中文版: https://www.w3.org/html/ig/zh...
然后可以再看ES6也就是ES2015的标准,虽然没有中文版,不过可以参考阮老师的ES6入门,顺便也可以瞄一眼ES2016的标准:
ES 2015: http://www.ecma-international...
ECMAScript 6入门教程: http://es6.ruanyifeng.com/
ES 2016: http://www.ecma-international...
期间有任何疑惑可以参考MDN上的JS参考文档,非常全面,涵盖了从入门到精通。
https://developer.mozilla.org...
看完这些再看ES2018就会非常轻松了:
https://tc39.github.io/ecma262/
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/83634.html
摘要:标准对象,语义由本规范定义的对象。这意味着虽然有,本质上依然是构造函数,并不能像那样表演多继承嵌套类等高难度动作。不过这里的并不是我们所说的数据类型,而是对象构造函数。 序 ECMAScript is an object-oriented programming language for performing computations and manipulating computat...
摘要:在写完容器源码分析系列文章中的最后一篇后,没敢懈怠,趁热打铁,花了天时间阅读了方面的源码。从今天开始,我将对部分的源码分析系列文章进行更新。全称是,即面向切面的编程,是一种开发理念。在中,切面只是一个概念,并没有一个具体的接口或类与此对应。 1. 简介 前一段时间,我学习了 Spring IOC 容器方面的源码,并写了数篇文章对此进行讲解。在写完 Spring IOC 容器源码分析系列...
摘要:前端日报精选漫谈函数式编程一十年踪迹的博客前端每周清单的优势与劣势有望超越在嵌入式及物联网的应用现状进阶系列高阶组件详解一前端之路译如何充分利用控制台掘金程序猿升级攻略众成翻译中文译如何充分利用控制台掘金前端从强制开启压缩探 2017-06-27 前端日报 精选 漫谈 JS 函数式编程(一) - 十年踪迹的博客前端每周清单: Vue的优势与劣势;Node.js有望超越Java;JS在嵌...
摘要:前端日报精选标准导读动感小前端的专栏大型网站前端使用图片格式的正确姿势腾讯前端大会现场笔记掘金在中学习数据结构与算法掘金周刊第期中文在中使用混合众成翻译已完结腾讯前端大会现场记录掘金翻译整合鼠标触摸和触控笔事件的掘金第期 2017-06-25 前端日报 精选 ECMAScript 2018 标准导读 - 动感小前端的专栏 - SegmentFault大型网站前端使用图片格式的正确姿势腾...
摘要:今天同学去面试,做了两道面试题全部做错了,发过来给道典型的面试题前端掘金在界中,开发人员的需求量一直居高不下。 排序算法 -- JavaScript 标准参考教程(alpha) - 前端 - 掘金来自《JavaScript 标准参考教程(alpha)》,by 阮一峰 目录 冒泡排序 简介 算法实现 选择排序 简介 算法实现 ... 图例详解那道 setTimeout 与循环闭包的经典面...
阅读 1330·2021-11-22 15:25
阅读 3314·2021-10-21 09:38
阅读 1529·2021-10-19 13:21
阅读 949·2021-09-06 15:00
阅读 1612·2019-08-30 15:44
阅读 2480·2019-08-29 15:40
阅读 3382·2019-08-29 13:44
阅读 1975·2019-08-26 16:56