本章内容包括:
- JavaScript历史回顾
- JavaScript的定义
- JavaScript和ECMAScript的关系
- JavaScript的不同版本
本章的下载内容请注意,所有本章的代码示例都可以在该书网站上的www.wiley.com/go/projavas...的本章代码下载部分找到。
当JavaScript于1995年首次出现时,其主要目的是处理一些之前由服务器端语言(如Perl)负责的输入验证。在那之前,需要往返服务器才能确定是否留空了必填字段或输入的值无效。Netscape Navigator试图通过引入JavaScript来改变这种情况。在当时,能够在客户端处理一些基本验证是一项令人兴奋的新功能,特别是在电话调制解调器的使用广泛的时候。由于关联的慢速,每次访问服务器都变成了一种对耐心的锻炼。
自那时以来,JavaScript已经发展成为市场上每个主要Web浏览器的重要特性。不再局限于简单的数据验证,JavaScript现在与浏览器窗口及其内容的几乎所有方面进行交互。JavaScript被认为是一种完整的编程语言,能够进行复杂的计算和交互,包括闭包、匿名(lambda)函数,甚至元编程。JavaScript已经成为Web的重要组成部分,即使是替代浏览器,包括移动电话上的浏览器和为残障用户设计的浏览器,也支持它。甚至微软,拥有自己的客户端脚本语言VBScript,最终在Internet Explorer的最早版本中也包含了自己的JavaScript实现。
JavaScript从一个简单的输入验证器崛起为强大的编程语言是无法预测的。JavaScript既是一个非常简单又非常复杂的语言,学习起来只需几分钟,但要掌握它则需要数年的时间。要充分发挥JavaScript的潜力,理解其性质、历史和局限性是很重要的。
简史
随着互联网的普及,对客户端脚本语言的需求逐渐增加。当时,尽管网页的大小和复杂性正在增长,大多数互联网用户仍然通过28.8 kbps调制解调器连接。为简单的表单验证而进行大量往返到服务器也增加了用户的痛苦。想象一下填写表单,点击提交按钮,等待30秒进行处理,然后收到一条消息,指示您忘记填写必填字段。当时处于技术创新的前沿,尼斯凯普(Netscape)开始认真考虑开发一种客户端脚本语言来处理简单的处理。
1995年,一位名为Brendan Eich的尼斯凯普开发人员开始为Netscape Navigator 2的发布开发一种名为Mocha(后来更名为LiveScript)的脚本语言。其目的是在浏览器和服务器上都使用它,服务器端将其称为LiveWire。
Netscape与Sun Microsystems达成了开发联盟,以在发布前及时完成LiveScript的实现。就在Netscape Navigator 2正式发布之前,Netscape将LiveScript的名称更改为JavaScript,以利用Java在媒体中受到的关注。
由于JavaScript 1.0取得了巨大成功,Netscape在Netscape Navigator 3中发布了1.1版本。新兴Web的普及程度达到了新的高度,Netscape定位自己成为市场的领导公司。在这个时候,微软决定投入更多资源开发一款竞争对手浏览器,名为Internet Explorer。在Netscape Navigator 3发布不久后,微软推出了Internet Explorer 3,其中包含了一个名为JScript的JavaScript实现(为了避免与Netscape可能存在的许可问题,选择这个名称)。这是微软于1996年8月进入Web浏览器领域的重要一步,对Netscape而言是一个声名狼藉的日子,但同时也代表JavaScript作为一种语言发展的重要一步。
微软对JavaScript的实现意味着存在两个不同的JavaScript版本:Netscape Navigator中的JavaScript和Internet Explorer中的JScript。与C和许多其他编程语言不同,JavaScript没有规定其语法或特性的标准,而这两个不同的版本只是突显了这个问题。由于行业担忧加剧,决定对该语言进行标准化。
1997年,JavaScript 1.1被提交给欧洲计算机制造商协会(Ecma)作为提案。技术委员会#39(TC39)被指定为"标准化通用、跨平台、供应商中立的脚本语言的语法和语义"(www.ecma-international.org/memento/TC3...)。由来自尼斯凯普、Sun、微软、Borland、NOMBAS等对脚本语言未来感兴趣的公司的程序员组成,TC39会议进行了数月的讨论,制定了ECMA-262,这是一个定义名为ECMAScript的新脚本语言的标准(通常发音为"ek-ma-script")。
第二年,国际标准化组织和国际电工委员会(ISO/IEC)也采纳了ECMAScript作为标准(ISO/IEC-16262)。从那时起,浏览器一直在尝试使用ECMAScript作为其JavaScript实现的基础,取得了不同程度的成功。
JavaScript的实现
尽管JavaScript和ECMAScript通常被视为同义词,但JavaScript远不止于ECMA-262中定义的内容。事实上,完整的JavaScript实现由以下三个明确定义的部分组成(见图1.1):
- 核心(ECMAScript)
- 文档对象模型(DOM)
- 浏览器对象模型(BOM)
ECMAScript
ECMAScript,在ECMA-262中定义的语言,不与Web浏览器绑定。实际上,该语言根本没有输入或输出的方法。ECMA-262将此语言定义为更强大的脚本语言可建立的基础。Web浏览器只是ECMAScript实现可能存在的众多主机环境之一。主机环境提供了ECMAScript的基础实现以及用于与环境本身交互的实现扩展。这些扩展,例如文档对象模型(DOM),使用ECMAScript的核心类型和语法提供了更特定于环境的附加功能。其他主机环境包括NodeJS,一个用于服务器端JavaScript的平台,以及日益过时的Adobe Flash。
如果ECMA-262没有涉及Web浏览器,那么它具体规定了什么?在非常基础的层面上,它描述了语言的以下部分:
- 语法
- 类型
- 语句
- 关键字
- 保留字
- 操作符
- 全局对象
ECMAScript只是一个实现规范中描述的所有方面的语言的描述,而JavaScript实现了ECMAScript。
ECMAScript版本
不同版本的ECMAScript被定义为"版本"(指的是描述该特定实现的ECMA-262版本)。ECMA-262的第一个版本基本上与尼斯凯普的JavaScript 1.1相同,但去掉了所有与特定于浏览器的代码的引用,并进行了一些小的更改:ECMA-262要求支持Unicode标准(以支持多种语言),并且对象必须是平台无关的(尼斯凯普JavaScript 1.1实际上在不同平台上有不同的对象实现,例如Date对象)。这是JavaScript 1.1和1.2不符合ECMA-262第一版的主要原因。
ECMA-262的第二版在很大程度上是编辑性的。该标准已更新以与ISO/IEC-16262严格一致,没有任何添加、更改或遗漏。ECMAScript实现通常不使用第二版作为一种符合性的度量标准。
ECMA-262的第三版是该标准的第一个真正的更新。它提供了对字符串处理、错误定义和数字输出的更新。它还添加了对正则表达式的支持,新的控制语句,try-catch异常处理,并对标准进行了小的更改,以更好地为国际化做准备。对许多人来说,这标志着ECMAScript成为真正的编程语言。
ECMA-262的第四版是该语言的一次完全改革。鉴于JavaScript在Web上的流行,开发人员开始修订ECMAScript以满足全球范围内Web开发不断增长的需求。作为回应,Ecma TC39重新召集以决定语言的未来。由此产生的规范基本上定义了一个基于第三版的几乎全新的语言。第四版包括强类型变量、新的语句和数据结构、真正的类和经典继承,以及与数据交互的新方式。
作为一个备选提案,一个名为"ECMAScript 3.1"的规范被TC39的一个小组委员会制定,他们认为第四版对语言来说是一个太大的飞跃。结果是一个较小的提案,对ECMAScript进行了渐进性的更改,可以在现有JavaScript引擎的基础上实现。最终,ES3.1小组赢得了TC39的支持,第四版的ECMA-262在正式发布之前被放弃。
ECMAScript 3.1变成了ECMA-262的第五版,并于2009年12月3日正式发布。第五版旨在澄清第三版的感知模糊之处并引入附加功能。新功能包括用于解析和序列化JSON数据的本地JSON对象,用于继承和高级属性定义的方法,以及引入了一种稍微改变ECMAScript引擎解释和执行代码方式的新的严格模式。第五版于2011年6月进行了维护修订;这仅仅是对规范的修正,没有引入新的语言或库功能。
ECMA-262的第六版,通常称为ES6、ES2015或ES Harmony,于2015年6月发布,并包含自其创建以来最重要的一系列规范增强。ES6增加了对类、模块、迭代器、生成器、箭头函数、Promises、反射、代理和一系列新的数据类型的正式支持。
ES6也标志着ECMAScript版本的年度发布的开始。因此,ECMAScript版本逐渐不再以递增整数(ES5、ES6)来命名,而开始以发布年份命名(ES2020、ES2021)。近期版本包括额外的字符串和数组方法、async/await、动态模块导入以及新的数值类型等功能。
ECMAScript符合性的含义是什么?
ECMA-262规定了ECMAScript符合性的定义。要被视为ECMAScript的实现,一个实现必须执行以下操作:
- 支持ECMA-262中描述的所有"类型、值、对象、属性、函数以及程序的语法和语义"。
- 支持Unicode字符标准。
此外,符合性的实现还可以执行以下操作:
- 添加"附加的类型、值、对象、属性和函数",这些在ECMA-262中未指定。ECMA-262将这些添加主要描述为规范中未给出的新对象或对象的新属性。
- 支持在ECMA-262中未定义的"程序和正则表达式语法"(这意味着允许修改和扩展内置的正则表达式支持)。
这些标准赋予实现开发者在基于ECMAScript开发新语言时极大的权力和灵活性,这在一定程度上解释了ECMAScript的受欢迎程度。
文档对象模型
文档对象模型(DOM)是一种用于XML的应用程序编程接口(API),后来被扩展以用于HTML。DOM将整个页面映射为节点层次结构。HTML或XML页面的每个部分都是包含不同类型数据的节点。考虑以下HTML页面:
xml
<html>
<head>
<title>Sample Page</title>
</head>
<body>
<p> Hello World!</p>
</body>
</html>
使用DOM,可以将这段代码绘制成节点层次结构图(见图1.2)。
通过创建代表文档的树结构,DOM使开发人员能够在内容和结构上拥有前所未有的控制水平。通过使用DOM API,节点可以轻松地被移除、添加、替换和修改。
DOM的必要性
随着Internet Explorer 4和Netscape Navigator 4分别支持不同形式的动态HTML(DHTML),开发人员首次可以在不重新加载页面的情况下修改网页的外观和内容。这代表了Web技术的巨大进步,但也带来了一个巨大的问题。Netscape和Microsoft在开发DHTML时选择了不同的方向,因此开发人员不能编写单个HTML页面,使其可以被任何Web浏览器访问。
人们决定必须采取措施来保持Web的跨平台性质。担心的是,如果不加以制约,Netscape和Microsoft将导致Web发展成两个专属于目标浏览器的独立派别。于是,负责创建Web通信标准的万维网联盟(W3C)开始致力于开发DOM。
DOM级别
DOM Level 1于1998年10月成为W3C推荐标准。它由两个模块组成:DOM核心提供了一种将基于XML的文档结构映射到允许轻松访问和操作文档任何部分的方式,而DOM HTML通过添加HTML特定的对象和方法来扩展DOM核心。
请注意,DOM并不特定于JavaScript,事实上已在许多其他语言中实现。然而,对于Web浏览器,DOM是使用ECMAScript实现的,现在构成了JavaScript语言的很大一部分。
DOM Level 1的目标是映射文档的结构,而DOM Level 2的目标则更为广泛。这个对原始DOM的扩展添加了对鼠标和用户界面事件(DHTML长期支持的事件)、范围和遍历(迭代DOM文档的方法)的支持,并通过对象接口支持层叠样式表(CSS)。在Level 1中引入的原始DOM核心还扩展为支持XML命名空间。
DOM Level 2引入了以下新的DOM模块来处理新类型的接口:
- DOM视图------描述用于跟踪文档各个视图的接口(例如,在CSS样式之前和之后的文档)
- DOM事件------描述用于事件和事件处理的接口
- DOM样式------描述用于处理元素基于CSS样式的接口
- DOM遍历和范围------描述用于遍历和操作文档树的接口
DOM Level 3通过引入一种统一加载和保存文档的方法(包含在称为DOM加载和保存的新模块中)以及验证文档的方法(DOM验证)进一步扩展了DOM。在Level 3中,DOM核心被扩展以支持XML 1.0的所有内容,包括XML Infoset、XPath和XML Base。
目前,W3C不再将DOM作为一系列级别进行维护,而是将其视为DOM Living Standard,其快照被称为DOM4。其中引入的内容包括添加突变观察器以替代突变事件。
请注意,在阅读关于DOM时,您可能会遇到对DOM Level 0 的引用。请注意,并没有称为DOM Level 0的标准;它只是DOM历史中的一个参考点。DOM Level 0 被认为是在Internet Explorer 4.0和Netscape Navigator 4.0中支持的原始DHTML。
其他DOMs
除了DOM核心和DOM HTML接口之外,还有几种其他语言的DOM标准被发布。以下列表中的语言基于XML,每个DOM都添加了特定于某个语言的方法和接口:
- 可伸缩矢量图形(Scalable Vector Graphics,SVG)1.0
- 数学标记语言(Mathematical Markup Language,MathML)1.0
- 同步多媒体集成语言(Synchronized Multimedia Integration Language,SMIL)
此外,其他语言也开发了自己的DOM实现,比如Mozilla的XML用户界面语言(XML User Interface Language,XUL)。然而,只有在前述列表中的语言是W3C的标准推荐。
浏览器对象模型
Internet Explorer 3和Netscape Navigator 3浏览器引入了一个浏览器对象模型(BOM),允许访问和操作浏览器窗口。通过BOM,开发人员可以在浏览器显示页面的上下文之外与其交互。使BOM真正独特且常常问题重重的是,它是JavaScript实现中唯一没有相关标准的部分。这一点在HTML5的引入时发生了变化,HTML5试图将BOM的许多部分纳入正式规范。由于HTML5的引入,围绕BOM的许多混乱已经消散。
主要来说,BOM涉及浏览器窗口和框架,但一般来说,任何特定于浏览器的JavaScript扩展都被视为BOM的一部分。以下是一些这样的扩展:
- 弹出新浏览器窗口的能力
- 移动、调整大小和关闭浏览器窗口的能力
- 提供有关浏览器的详细信息的导航器对象
- 提供有关浏览器中加载的页面的详细信息的位置对象
- 提供有关用户屏幕分辨率的详细信息的屏幕对象
- 提供有关浏览器内存消耗、导航行为和时间统计的详细信息的性能对象
- 对Cookies的支持
- 自定义对象,如XMLHttpRequest
由于BOM长时间没有标准存在,每个浏览器都有自己的实现。虽然有一些事实上的标准,比如有一个窗口对象和一个导航器对象,但每个浏览器都为这些和其他对象定义了自己的属性和方法。随着HTML5的推出,BOM的实现细节预计将以更加兼容的方式增长。有关BOM的详细讨论包含在第12章"浏览器对象模型"中。
总结
JavaScript是一种旨在与网页交互的脚本语言,由以下三个明确定义的部分组成:
- ECMAScript,定义在ECMA-262中,提供核心功能。
- 文档对象模型(DOM),提供用于处理网页内容的方法和接口。
- 浏览器对象模型(BOM),提供用于与浏览器交互的方法和接口。
在五大主要的网络浏览器(Edge、Firefox、Chrome、Safari和Opera)中,对JavaScript的这三个部分的支持程度有所不同。对于最新的ECMAScript功能,各浏览器的支持通常都很好。对于DOM的支持有所差异,但Level 3的兼容性越来越成为规范。 BOM在HTML5中被规范化,但在不同浏览器中可能存在差异,尽管有一些被假定为可用的共同特性。