發佈於 2018-07-20
之前的几篇,我们介绍了 HTML 和 CSS 基础知识,对于网页结构和样式,都有了一定的了解。从这篇之后,我们将介绍网页中另一个重要知识 - JavaScript。我们将参考《JavaScript 高级程序设计》,对每章的重要知识进行详细的讲解。
JavaScript 堪称世界上被人误解最深的编程语言,常被嘲为”玩具语言”,但在它看似简洁的外衣下,还隐藏着强大的语言特性。JavaScript 目前广泛应用于众多知名应用中,对于网页和移动开发者来说,深入理解 JavaScript 就尤有必要。
JavaScript 最初的目的是为了”让网页动起来”。 这种编程语言我们称之为脚本。它们可以写在 HTML 中,在页面加载的时候会自动执行。脚本作为纯文本存在和执行。它们不需要特殊的准备或编译即可运行。
JavaScript 在刚诞生的时候,它的名字叫”LiveScript”。但是因为当时 Java 很流行,所以决定将一种新语言定位为 Java 的”弟弟”会有所帮助。随着 JavaScript 的发展,它已经变成了一门独立的语言,同时也有了自己的语言规范 ECMAScript。现在,它和 Java 之间没有任何关系。
一个完整的 JavaScript 实现应由三个不同部分组成:
ECMAScript 与 Web 浏览器没有依赖关系。我们常见的 Web 浏览器只是 ECMAScript 的宿主环境之一。 宿主环境会提供 ECMAScript 的基本实现以及该语言的扩展,以便语言与宿主对接交互。如: DOM 就是浏览器宿主对 ECMAScript 语言实现的扩展。 我们知道的 Node 就是 ECMAScript 在服务器端的宿主环境。 ECMAScript 规定了:
BOM(Browser Object Model)是 JavaScript 提供给我们来操纵浏览器的手段。如: 我们可以使用 BOM 调整浏览器的窗口高度、宽度、位置等。在 HTML5 中被纳入标准。
简单来说,DOM(Document Object Model)是一套对文档内容进行抽象和概念化的方法。 最早的 DOM 未成标准,各个浏览器的实现都不同,在实际工作中,很多脚本不得不编写多次。在 1998 年 10 月,完成了 DOM Level 1。标准化的 DOM 可以让任何一种编程语言对使用任何一种标记语言编写的任何一份文档进行操控。
W3C 的 DOM 定义: 一个与系统平台和编程语言无关的接口,程序和脚本可以通过这个接口动态的访问和修改文档的结构,内容和样式。
请注意: DOM 并不只针对 JavaScript 的。
DOM1 由 2 个模块组成:
DOM 核心规定了如何映射基于 XML 的文档结构,DOM HTML 则在 DOM 核心基础上加以扩展,添加了针对 HTML 的对象和方法。
DOM2 引入了下列新模块:
DOM3 进一步扩展 DOM:
我们知道,浏览器内核包括:
常见的渲染引擎有: blank、webcore 等,常见的 JS 引擎有: jscore、chakra、V8 等。
引擎很复杂,但是基本原理很简单:
引擎会对流程中的每个阶段都进行优化。它甚至可以在运行时监视编译的脚本,分析数据流并根据这些对机器代码应用优化。最后,脚本会执行地非常快。
浏览器中的 JavaScript 可以完成下面这些事:
最近出现了很多不同的语言,这些语言在浏览器中执行之前,都会被编译(转化)成 JavaScript。 现代化的工具使得编译速度非常快速和透明,实际上允许开发人员使用另一种语言编写代码并将其自动转换为 JavaScript。
这些语言的例子有:
向 HTML 页面插入 JavaScript 的主要方法,就是使用 script 元素。其定义了4个属性:
使用 script 元素的方式有两种:
注意: 在使用嵌入代码时,不要在代码中出现 “</script>” 字符串。使用转义解决这个问题。 当使用嵌入代码时,解释器对 script 元素内部的所有代码求值完毕前,页面的其余内容都不会被浏览器加载显示。 当使用外部文件时,页面的处理也会暂时停止。 也就是说,无论如何使用 script 元素,只要不存在 async 或者 defer 属性,浏览器都会按照 script 元素在页面出现的先后顺序对他们依次解析,即只有第一个 script 元素中的所有代码解析完毕,才会开始解析下一个。
为了避免出现上述所说的阻塞问题,现代 Web 应用一般把 JavaScript 引用放到 body 结束标记之前。
该属性表示: 立即下载,延迟执行。并且 HTML5 要求脚本按照出现的先后顺序,在其他同步脚本执行后,DOMContentLoaded 事件前依次执行,因此第一个延迟脚本会先于第二个延迟脚本执行。最佳实践是只有一个延迟脚本。
与 defer 一样,都用于改变脚本的加载行为,都是告诉浏览器立即下载,但是与 defer 不同的是: 标记为 async 属性的脚本不能保证执行顺序。因此确保脚本之间互不依赖非常重要。 异步脚本一定会在 load 事件之前执行,可能会在 DOMContentLoaded 事件之前或之后执行。
我们应尽量使用外部文件,因为:
noscript 元素的内容只有在下面两种情况才显示:
除此之外,浏览器都不会显示 noscript 元素中的内容。