当JavaScript在1995年刚出现的时候,它最主要的目的是处理之前留给比如Perl服务端语言来处理的输入校验,在那之前,前端的输入需要往返服务器以确定某个必需字段是否为空或无效。网景浏览器试图通过引入 JavaScript 来改变这种情况,毕竟在广泛使用电话调制解调器的时代,能在客户端处理一些基本的校验能力是一个令人兴奋的新功能。因为每次缓慢的访问锻炼着人们的耐心。
从那时起,JavaScript 已发展成为市场上每个主要Web浏览器的重要功能。JavaScript 不再局限于简单的数据验证,现在可以与浏览器窗口及其内容的几乎所有方面进行交互。JavaScript 被认为是一种完整的编程语言,能够进行复杂的计算和交互,包括闭包,匿名(lambda)函数,甚至元编程。JavaScript 已经成为 web 的重要组成部分,甚至包括手机和为残疾用户设计的浏览器在内的其他浏览器都支持它。即使是微软,拥有自己的客户端脚本语言 VBScript,最终也在最早版本的 Internet Explorer 中包含了自己的 JavaScript 实现。
JavaScript从一个简单的输入验证器兴起成为一种强大的编程语言是无法预测的。 JavaScript既是一种非常简单又非常复杂的语言,花费几分钟的时间就能学习,但需要数年的时间才能掌握。要开始充分利用 JavaScript 的潜力,了解它的性质、历史和局限性是很重要的。
# 简短的历史
随着网络的普及,对客户端脚本语言的需求逐渐增长。 当时,即使网页的大小和复杂性不断增长,大多数Internet用户仍通过28.8 kbps的调制解调器进行连接。 使用户感到痛苦的是,简单表单验证所需的服务器往返次数众多。 想象一下,填写表单,单击“提交”按钮,等待30秒进行处理,然后看到一条消息,提示您忘记填写必填字段。 当时,Netscape处于技术创新的最前沿,开始认真考虑开发客户端脚本语言以处理简单处理的问题。
1995年,一位名叫Brendan Eich的Netscape开发人员开始为发布Netscape Navigator 2开发一种名为Mocha(后来更名为LiveScript)的脚本语言。其目的是要在浏览器和服务器上都使用它, 称为LiveWire。
Netscape与Sun Microsystems结成了开发联盟,以便及时完成LiveScript的实现。就在Netscape Navigator 2正式发布之前,Netscape将LiveScript的名称改为JavaScript,以利用Java从媒体那里得到的轰动。
因为JavaScript1.0很受欢迎,所以Netscape在Netscape Navigator 3中发布了1.1版。初出茅庐的网络正达到一个新的高度,网景已经把自己定位为市场上的领先公司。此时,微软决定将更多的资源投入到一款名为Internet Explorer的竞争性浏览器中。在Netscape Navigator 3发布后不久,微软引入了带有JavaScript实现的internetexplorer3,称为JScript(这样做是为了避免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/TC39.htm)。TC39由来自Netscape、Sun、Microsoft、Borland、NOMBAS和其他对脚本未来感兴趣的公司的程序员组成,他们花了几个月的时间讨论了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)
FIGURE 1-1
# ECMAScript
ECMAScript是ECMA-262中定义的语言,它与web浏览器无关。实际上,该语言没有任何输入或输出方法。ECMA-262将这种语言定义为可以构建更健壮的脚本语言的基础。Web浏览器只是其中可能存在ECMAScript实现的一个宿主环境。宿主环境提供ECMAScript的基本实现以及旨在与环境本身交互的实现扩展。 诸如文档对象模型(DOM)之类的扩展使用ECMAScript的核心类型和语法来提供特定于环境的附加功能。其他宿主环境包括NodeJS(一个服务器端JavaScript平台),以及越来越过时的Adobe Flash。
如果ECMA-262不引用web浏览器,它具体指定了什么?在非常基本的层面上,它描述了语言的以下部分:
- 语法
- 类型
- 声明
- 关键词
- 保留字
- 操作符
- 全局对象
ECMAScript只是对语言的描述,该语言实现了规范中描述的所有方面。 JavaScript实现ECMAScript,同样Adobe 实现 ActionScript。
# ECMAScript 版本
ECMAScript的不同版本被定义为版本(指描述特定实现的ECMA-262版本)。ECMA-262的最新版本是2016年发布的第7版。ECMA-262的第一版本质上与Netscape的JavaScript1.1相同,但删除了所有对浏览器特定代码的引用,并做了一些小改动:ECMA-262要求支持Unicode标准(以支持多种语言),并且对象是独立于平台的(Netscape JavaScript1.1实际上具有不同的对象的实现,例如日期对象,取决于平台)。这是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再次召开会议,决定该语言的未来。最终的规范定义了一种基于第三版的几乎全新的语言。第四版包括强类型变量(strongly typed variables)、new 声明(new statements)和数据结构、true classes和经典继承,以及与数据交互的新方法。
作为一个替代方案,TC39的一个小组委员会开发了一个名为“ECMAScript 3.1”的规范,作为该语言的一个较小的改进,该小组委员会认为第四版对该语言来说太大了。结果是一个较小的提议,对ECMAScript进行了增量更改,可以在现有JavaScript引擎的基础上实现。最终,ES3.1小组委员会赢得了TC39的支持,ECMA-262的第四版在正式出版之前就被废弃了。
EcmaScript3.1成为第五版ECMA-262,并于2009年12月3日正式发布。第五版试图澄清第三版的模糊性,并引入附加功能。新功能包括用于解析和序列化JSON数据的本地JSON对象、用于继承和高级属性定义的方法,以及包含新的strict模式,该模式略微增强了ECMAScript引擎解释和执行代码的方式。第五版在2011年6月进行了维护修订;这只是为了规范中的更正,没有引入新的语言或库功能。
ECMA-262的第六版通俗地称为ES6、ES2015或ES Harmony,于2015年6月出版,其中包含了自规范诞生以来最重要的改进。ES6增加了对类、模块、迭代器、生成器、箭头函数、承诺(promises)、反射(refection)、代理(proxies)和大量新数据类型的正式支持。
第七版ECMA-262被称为ES7或ES2016,于2016年6月出版。此修订版仅包含少量语法添加,如Array.prototype.includes和幂运算符。
第八版ECMA-262称为ES8或ES2017,于2017年1月定稿。此修订版包括异步迭代、rest和spread属性、新正则表达式功能的集合、Promise finally()catchall处理程序和模板文本修订版。
第九版ECMA-262仍在定稿中,但在第三阶段已经有了大量的功能。它最重要的附加功能可能是动态导入ES6模块。
# ECMAScript一致性是什么意思?
ECMA-262给出了ECMAScript一致性的定义。要被认为是ECMAScript的实现,实现必须做到以下几点:
支持ECMA-262中描述的所有“类型、值、对象、属性、函数、程序语法和语义”。
支持Unicode字符标准。
此外,一致性实现可以执行以下操作:
添加ECMA-262中未指定的“附加类型、值、对象、属性和函数”。ECMA-262将这些添加描述为规范中未给出的主要新对象或对象的新属性。
支持ECMA-262中未定义的“程序和正则表达式语法”(意味着允许更改和扩展内置正则表达式支持)。
这些标准为实现开发人员开发基于ECMAScript的新语言提供了极大的能力和灵活性,这在一定程度上解释了ECMAScript的流行。
# Web浏览器中的ECMAScript支持
Netscape Navigator 3在1996年随JavaScript1.1一起提供。同样的JavaScript1.1规范随后作为新标准Ecma-262的提案提交给了Ecma。随着JavaScript的爆炸式流行,Netscape非常高兴地开始开发1.2版。然而,有一个问题:Ecma还没有接受Netscape的提议。
在Netscape Navigator 3发布后不久,微软推出了Internet Explorer 3。JScript 1.0附带了这个版本的IE,它应该等同于JavaScript 1.1。然而,由于没有文档记录和不正确的复制特性,JScript 1.0远远低于JavaScript 1.1。
Netscape Navigator 4在1997年与JavaScript 1.2一起发布,之后ECMA-262的第一版被接受并在当年晚些时候标准化。因此,JavaScript 1.2与ECMAScript的第一版不兼容,尽管ECMAScript应该基于javascript1.1。
JScript的下一次更新发生在带有JScript版本3.0的Internet Explorer 4中(版本2.0在Microsoft Internet Information Server版本3.0中发布,但从未包含在浏览器中)。微软发布了一份新闻稿,宣称JScript 3.0是世界上第一种真正符合Ecma的脚本语言。当时,ECMA-262还没有最终确定,因此JScript 3.0遭遇了与JavaScript 1.2相同的命运:它不符合最终的ECMAScript标准。
Netscape选择将Netscape Navigator 4.06中的JavaScript实现更新为JavaScript 1.3,这使得Netscape完全符合ECMA-262的第一版。Netscape增加了对Unicode标准的支持,使所有对象都独立于平台,同时保留了JavaScript1.2中引入的功能。
当Netscape将其源代码作为Mozilla项目发布给公众时,预计JavaScript1.4将随Netscape Navigator 5一起提供。然而,一个彻底重新设计Netscape代码的激进决定使这一努力脱轨。JavaScript 1.4只是作为Netscape Enterprise server的服务器端语言发布的,从未进入web浏览器。
到2008年,五大浏览器(Internet Explorer、Firefox、Safari、Chrome和Opera)都符合ECMA-262的第三版。InternetExplorer8是第一个开始实施ECMA-262规范第五版的浏览器,并在InternetExplorer9中提供了完整的支持。火狐4很快就跟进了。下表列出了最流行的web浏览器中的ECMAScript支持。
BROWSER | ECMASCRIPT COMPLIANCE |
---|---|
Netscape Navigator 2 | — |
Netscape Navigator 3 | — |
Netscape Navigator 4–4.05 | — |
Netscape Navigator 4.06–4.79 | Edition 1 |
Netscape 6+ (Mozilla 0.6.0+) | Edition 3 |
Internet Explorer 3 | — |
Internet Explorer 4 | — |
Internet Explorer 5 | Edition 1 |
Internet Explorer 5.5–8 | Edition 3 |
Internet Explorer 9 | Edition 5* |
Internet Explorer 10–11 | Edition 5 |
Edge 12+ | Edition 6 |
Opera 6–7.1 | Edition 2 |
Opera 7.2+ | Edition 3 |
Opera 15–28 | Edition 5 |
Opera 29–35 | Edition 6* |
Opera 36+ | Edition 6 |
Safari 1–2.0.x | Edition 3* |
Safari 3.1–5.1 | Edition 5* |
Safari 6–8 | Edition 5 |
Safari 9+ | Edition 6 |
iOS Safari 3.2–5.1 | Edition 5* |
iOS Safari 6–8.4 | Edition 5 |
iOS Safari 9.2+ | Edition 6 |
Chrome 1–3 | Edition 3 |
Chrome 4–22 | Edition 5* |
Chrome 23+ | Edition 5 |
Chrome 42–48 | Edition 6* |
Chrome 49+ | Edition 6 |
Firefox 1–2 | Edition 3 |
Firefox 3.0.x–20 | Edition 5* |
Firefox 21–44 | Edition 5 |
Firefox 45+ | Edition 6 |
* 不完全实现
# 文档对象模型
文档对象模型(DOM)是XML的应用程序编程接口(API),已扩展为在HTML中使用。 DOM将整个页面映射为节点的层次结构。 HTML或XML页面的每个部分都是一种节点,其中包含不同种类的数据。 考虑以下HTML页面:
<html>
<head>
<title>Sample Page</title></head>
<body>
<p> Hello World!</p>
</body>
</html>
这段代码可以用DOM绘制成节点层次结构图(见图1-2)。
通过创建表示文档的树,DOM允许开发人员对其内容和结构进行前所未有的控制。使用DOM API可以轻松地删除、添加、替换和修改节点。
# 为什么需要DOM
随着InternetExplorer4和NetscapeNavigator4各自支持不同形式的动态HTML(DHTML),开发人员第一次可以在不重新加载网页的情况下改变网页的外观和内容。这代表着web技术的巨大进步,但同时也是一个巨大的问题。Netscape和微软分别开发DHTML,从而结束了开发人员可以编写任何web浏览器都可以访问的单个HTML页面的时期。
他们决定采取一些措施来保护web的跨平台特性。人们担心的是,如果网景和微软不加以控制,网络就会发展成两个截然不同的派别,专门针对特定的浏览器。就在那时,负责创建Web通信标准的机构万维网联盟(W3C)开始研究DOM。
# DOM 层级
DOM Level 1在1998年10月成为W3C推荐标准。它由两个模块组成:DOM Core和DOM HTML。前者提供了一种映射基于xml的文档结构的方法,从而方便地访问和操作文档的任何部分;后者通过添加特定于HTML的对象和方法扩展了DOM Core。
WARNING
请注意,DOM不是特定于javascript的,实际上在许多其他语言中都有。但是,对于web浏览器,DOM是使用ECMAScript实现的,它现在构成了JavaScript语言的很大一部分。
DOM Level 1的目标是绘制文档的结构图,而DOM Level 2的目标要广泛得多。原始DOM的这个扩展增加了对鼠标和用户界面事件(DHTML长期支持)、范围和遍历(在DOM文档上迭代的方法)的支持,以及对通过对象接口级联样式表(CSS)的支持。在级别1中引入的原始DOM核心也进行了扩展,以包括对XML名称空间的支持。
DOM Level 2引入了DOM的以下新模块来处理新类型的接口:
- DOM视图——描述用于跟踪文档的各种视图的接口(例如,在CSS样式化之前和之后的文档)
- DOM事件——描述事件和事件处理的接口
- DOM样式——描述处理基于css的元素样式的接口
- DOM遍历和范围——描述遍历和操作文档树的接口
DOM Level 3进一步扩展了DOM,引入了以统一的方式加载和保存文档的方法(包含在一个名为DOM load和save的新模块中)和验证文档的方法(DOM验证)。在第3级中,DOM核心被扩展为支持所有XML 1.0,包括XML Infoset、XPath和XML Base。 目前,W3C不再将DOM维护为一组级别,而是作为DOM的生活标准,其快照称为DOM4。在它的介绍中,增加了突变观察者来代替突变事件。
WARNING
在阅读有关DOM的信息时,您可能会遇到对DOM Level 0的引用。注意,没有称为DOM Level 0的标准;它只是DOM历史上的一个参考点。DOM Level 0被认为是Internet Explorer 4.0和Netscape Navigator 4.0中支持的原始DHTML。
# 其它DOM
除了DOM核心和DOM HTML接口之外,还有其他几种语言也发布了自己的DOM标准。以下列表中的语言是基于xml的,每个DOM都添加了特定语言特有的方法和接口:
- 可缩放向量图形(SVG) 1.0
- 数学标记语言(MathML) 1.0
- 同步多媒体集成语言(SMIL)
此外,其他语言也开发了自己的DOM实现,比如Mozilla的XML用户界面语言(XML User Interface Language, XUL)。然而,只有上述列表中的语言是W3C的标准推荐。
# Web浏览器中的DOM支持
在web浏览器开始实现DOM之前,DOM已经成为标准有一段时间了。Internet Explorer在版本5中进行了第一次尝试,但是直到版本5.5实现了DOM级别1的大部分内容之后,它才获得了真正的DOM支持。Internet Explorer在版本6和7中没有引入新的DOM功能,尽管版本8引入了一些bug修复。
对于Netscape,在引入Netscape 6 (Mozilla 0.6.0)之前不存在DOM支持。在Netscape 7之后,Mozilla将其开发工作转移到Firefox浏览器上。Firefox 3+支持所有级别1、几乎所有级别2和部分级别3。(Mozilla开发团队的目标是构建一个100%符合标准的浏览器,他们的工作得到了回报。)
对于大多数浏览器厂商来说,DOM支持已经成为了一个非常重要的优先级,他们一直在努力改进对每个版本的支持。下表显示了对流行浏览器的DOM支持。
BROWSER | DOM COMPLIANCE |
---|---|
Netscape Navigator 1.–4.x | — |
Netscape 6+ (Mozilla 0.6.0+) | Level 1, Level 2 (almost all), Level 3 (partial) |
Internet Explorer 2–4.x | — |
Internet Explorer 5 | Level 1 (minimal) |
Internet Explorer 5.5–8 | Level 1 (almost all) |
Internet Explorer 9+ | Level 1, Level 2, Level 3 |
Edge | Level 1, Level 2, Level 3 |
Opera 1–6 | — |
Opera 7–8.x | Level 1 (almost all), Level 2 (partial) |
Opera 9–9.9 | Level 1, Level 2 (almost all), Level 3 (partial) |
Opera 10+ | Level 1, Level 2, Level 3 (partial) |
Safari 1.0.x | Level 1 |
Safari 2+ | Level 1, Level 2 (partial), Level 3 (partial) |
iOS Safari 3.2+ | Level 1, Level 2 (partial), Level 3 (partial) |
Chrome 1+ | Level 1, Level 2 (partial), Level 3 (partial) |
Firefox 1+ | Level 1, Level 2 (almost all), Level 3 (partial) |
这个兼容性表的内容一直在变化,只能作为历史参考。
# 浏览器对象模型
Internet Explorer 3和Netscape Navigator 3浏览器提供了一个允许访问和操作浏览器窗口的浏览器对象模型(Browser Object Model, BOM)。使用BOM,开发人员可以在显示页面的上下文之外与浏览器交互。BOM真正的独特之处在于,它是JavaScript实现中唯一没有相关标准的部分,而且常常会出现问题。随着HTML5的引入,情况发生了变化,HTML5试图将BOM的大部分编码成正式规范的一部分。多亏了HTML5,围绕BOM的许多困惑已经消散。
基本上,BOM处理浏览器窗口和框架,但一般来说,JavaScript的任何浏览器特定扩展都被视为BOM的一部分。以下是一些此类扩展:
- 能够弹出新的浏览器窗口
- 移动、调整和关闭浏览器窗口的功能
- navigator对象,它提供有关浏览器的详细信息
- location对象,它提供有关在浏览器中加载的页的详细信息
- screen对象,它提供有关用户屏幕分辨率的详细信息
- performance对象,它提供有关浏览器内存的详细信息
- 对cookies的支持
- 自定义对象,如XMLHttpRequest和Internet Explorer的ActiveXObject
因为BOM已经很久没有标准了,所以每个浏览器都有自己的实现。有一些事实上的标准,比如有一个窗口对象和一个导航器对象,但是每个浏览器都为这些对象和其他对象定义了自己的属性和方法。现在有了HTML5的帮助,BOM的实现细节有望以更兼容的方式增长。关于BOM的详细讨论包含在“浏览器对象模型”一章中。
# JavaScript 的版本
Mozilla是最早的Netscape的后代,是唯一一个延续了最初的JavaScript版本编号顺序的浏览器供应商。当Netscape的源代码被剥离成一个开放源码项目(称为Mozilla项目)时,JavaScript的最后一个浏览器版本是1.3。(如前所述,版本1.4仅在服务器上实现。)随着Mozilla基金会继续JavaScript的工作,添加了新的特性、关键字和语法,JavaScript版本号也随之增加。下表显示了Netscape/Mozilla浏览器的JavaScript版本进程。
BROWSER | JAVASCRIPT VERSION |
---|---|
Netscape Navigator 2 | 1.0 |
Netscape Navigator 3 | 1.1 |
Netscape Navigator 4 | 1.2 |
Netscape Navigator 4.06 | 1.3 |
Netscape 6+ (Mozilla 0.6.0+) | 1.5 |
Firefox 1 | 1.5 |
Firefox 1.5 | 1.6 |
Firefox 2 | 1.7 |
Firefox 3 | 1.8 |
Firefox 3.5 | 1.8.1 |
Firefox 3.6 | 1.8.2 |
Firefox 4 | 1.8.5 |
编号方案基于Firefox4将采用JavaScript2.0的想法,在此之前版本号的每一个增量都表明JavaScript2.0的实现与2.0的提议有多接近。尽管这是最初的计划,但是JavaScript的发展已经不可能了。目前还没有JavaScript 2.0的目标实现,这种类型的版本控制在Firefox 4发布之后就停止了。
WARNING
需要注意的是,只有Netscape/Mozilla浏览器遵循这个版本控制方案。例如,Internet Explorer有不同的JScript版本号。这些JScript版本与上表中提到的JavaScript版本完全不对应。此外,大多数浏览器都会根据其ECMAScript遵从性和DOM支持的级别来讨论JavaScript支持。
# 总结
JavaScript是一种脚本语言,旨在与web页面交互,它由以下三个不同的部分组成:
- ECMAScript,在ECMA-262中定义,它提供核心功能
- 文档对象模型(DOM),它提供了处理网页内容的方法和接口
- 浏览器对象模型(BOM),它提供了与浏览交互的方法和接口
在五种主要的web浏览器(Internet Explorer、Firefox、Chrome、Safari和Opera)中,对JavaScript的三个部分的支持程度各不相同。对ECMAScript 5的支持通常在所有浏览器中都很好,对ECMAScript 6和7的支持也在不断增加。对DOM的支持各不相同,但3级遵从性越来越规范。在HTML5中编码的BOM可能因浏览器而异,尽管有一些共性被认为是可用的。
← 前言 html 中的 JavaScript →