在如今种类众多的编程语言中,JavaScript是一个非常特殊的存在。如果从语言设计的角度来分析,JavaScript应该被归类为基于原型的、解释型的高级编程语言。也就是说,尽管JavaScript在语法上与Java、C/C++非常相似,但从编程方法的应用上来说,它受Self和Scheme这类语言的影响多一些,因此在具体使用方式上更接近后者。除此之外,JavaScript还是一门支持多种编程范式的语言。它支持面向对象编程、指令式编程以及函数式编程,因而具有极为灵活的表达能力。
而在适用领域方面,JavaScript从最初的纯浏览器端脚本语言,逐步发展成了如今这样一门可在Web浏览器端、移动设备端、桌面应用端以及服务器端通用的强大编程语言。
如前所述,如果想判断一门编程语言是否适用于某个领域,很大程度上要去分析该领域是否能发挥出该语言的特性优势。既然我们已经对JavaScript的语言特性有了一定的了解,那么接下来就可以对这门语言的适用领域做一些分析了。这些分析将有助于初学者明确JavaScript适合用来解决什么问题,不适合用来解决什么问题,以便厘清自己的学习需求和努力方向。以下是一些适合用JavaScript来解决问题的领域。
除此之外,JavaScript有时候还会被用来实现一些Web浏览器的扩展与插件、移动端的一些应用,甚至一些用于系统管理的命令行脚本。总而言之,虽然目前JavaScript已经发展成了一门无处不在的全能型编程语言,但还是得注意语言特性的发挥,能发挥出其特性优势的领域才是它真正适用的领域。反之,不分场合地强行使用这门语言只会弄巧成拙、事倍功半。
选哪一本书做教程?
这是一本专注于JavaScript本身及其运行环境的书,而JavaScript语言主要是一门面向Web应用程序开发领域的编程语言,即使是用于开发桌面应用程序的Electron框架,它在本质上也可以被视为一个针对Google Chromium浏览器(Chrome浏览器的开源版本)的扩展,它的用户界面布局也主要依靠HTML、CSS及其扩展技术来完成。所以在阅读本书之前,希望读者已经掌握了与HTML和CSS相关的基础知识。
由于本书只专注于讨论如何使用JavaScript语言与其运行环境提供的接口,因此不打算过多地涉及时下五花八门的开发框架。这样做主要是基于两个方面的考虑。第一,介绍JavaScript语言及其运行环境本身就足以撑起一本结构完整、内容丰富的书了。如果再加上众多开发框架的介绍,就会淡化这本书的主题,并使其臃肿不堪。第二,JavaScript社区的开发框架不仅五花八门,选择众多,而且更新换代极为迅速。这意味着,即使这本书介绍了客户端的React框架、服务端的Express框架、桌面端的Electron框架,也很有可能到这本书写完并最终出版之时,开发者已经有了更好的选择。正所谓“授之以鱼不如授之以渔”,读者真正应该掌握的是快速学习新框架的能力,这就需要读者了解这些框架的设计思路,理解为什么决定开放那些接口给用户,以及为什么要对用户隐藏那些实现,从而习得开发框架的能力。换句话说,虽然不必重复发明轮子,但一个优秀的工程师或设计师应该了解轮子是如何被发明的,这样才能清楚用什么样的轮子构建什么样的车。
另外,要想学好一门语言,无论是英语、汉语这样的自然语言还是C/C++、Java、JavaScript这样的编程语言,最好的办法就是尽可能地在实践中使用它,在实际需求的驱动下模仿、试错并总结经验。所以本书不鼓励读者使用可直接复制和粘贴的代码示例,我更希望读者“自己动手”去模仿本书提供的示例,亲手将自己想要执行的代码输入计算机中,并观察它们是如何工作的,然后试着修改它们,并验证其结果是否符合预期。如果符合预期;就总结当下的经验;如果不符合预期,则去思考应该做哪些调整使其符合预期。如此周而复始,才能让学习事半功倍。
简而言之,本书是一本涵盖Web前后端全栈开发的JavaScript入门教程,从基于ECMAScript标准的基本语法开始,循序渐进、层层深入地介绍JavaScript在浏览器端、服务器端的开发思路、设计理念。在此过程中,本书提供大量可读性强、能够正确运行的代码示例,以帮助读者理解书中介绍的技术、概念、编程思想与程序设计理念。
除了前言部分,本书的主体由三部分组成。第一部分讨论的是JavaScript语言的核心,这里用4章的篇幅介绍JavaScript语言由ECMAScript标准所规范的基本语法、面向对象机制、异步编程方法等直接与语言本身相关的内容。第二部分讨论的是前端开发,这里用5章的篇幅来介绍JavaScript在浏览器端的使用,包括DOM和BOM组件、AJAX技术等。第三部分讨论的是后端开发,这里用4章的篇幅来介绍JavaScript在Node.js平台中的使用,包括如何创建Web服务器并响应浏览器的请求,如何读取服务器上的文件或在服务器上执行数据库操作等。下面是本书各章的内容简介。
第1章,JavaScript简介。这一章会让读者对JavaScript这门编程语言有一个整体的认知。首先详细介绍JavaScript的起源以及它的标准化过程,帮助读者了解它的组成和特性,以及能发挥其特性优势的领域。然后介绍如何搭建可用于执行/调试JavaScript脚本的运行环境。
第2章,变量、表达式与语句。这一章介绍注释、变量、表达式以及语句等JavaScript的基本语法元素及其用法。首先对如何在JavaScript代码中进行注释做一些相关的介绍和建议。然后介绍变量的定义、命名规范、数据类型、存储类型等基础知识,以及用于操作变量的操作符。最后讲解如何编写程序的最基本执行单位——语句,其中包括用于选择执行的条件语句和用于重复执行的循环语句。
第3章,函数与对象。这一章介绍封装的概念及其在编程中的意义。首先介绍如何将归属于不同任务的操作分离出来,封装成独立的函数并调用它。然后介绍如何将函数与其相关的数据进一步封装成对象。最后由对象的定义进一步引出数据结构的概念,帮助读者理解数据结构在编程中的作用。除此之外,本着“不要重复发明轮子”的基本编程原则,本章还将详细介绍一系列JavaScript中常用的内置函数和对象。
第4章,面向对象编程。这一章介绍如何在JavaScript中实现面向对象编程。首先从程序设计的需求面切入,解释什么是面向对象编程,以及将调用接口与具体实现分开设计的意义。然后详细介绍如何在构建对象的过程中将实现细节隐藏起来,并开放公有接口。接着进入面向对象编程的核心内容:类与类之间的继承关系。在针对该内容的讨论中,先详细介绍ES6新增的类定义与类继承语法,随即将时间拉回到ES6标准发布之前,为读者说明在没有类定义与继承语法的情况下,如何在JavaScript中实现面向对象编程。最后再回过头来证明ES6新增的语法并没有改变这一继承机制,它只是一个在使用上提供方便的“语法糖”。
第5章,异步编程。这一章介绍异步编程的概念及其用法与执行机制,其主要内容包括事件处理与Promise对象。本章会详细说明异步编程在JavaScript编程中的特殊地位,它是使用该语言编程最核心的技能之一。换句话说,只有掌握了异步编程,JavaScript在我们手中才能展现出其真正强大的能力。
第6章,前端编程概述。这一章介绍服务器和浏览器在Web应用程序架构中的分工,以便帮助读者明确前端编程的任务。作为本书第二部分的开篇,本章会介绍前端编程中具体要使用的对象,其中包含用于处理HTML和XML文档页面元素的DOM、用于处理浏览器部分功能的BOM、用于支持AJAX编程的XMLHTTP系列对象,以及用于装饰Web页面的CSS等美工技术。
第7章,DOM标准与使用。这一章介绍如何在前端处理XML与HTML文档的DOM对象。首先介绍DOM出现的历史背景以及标准化过程。然后详细介绍DOM的使用方式及其背后的编程思维。简而言之,DOM的本质是将浏览器所读取到的XML或HTML文档映射到内存中的一个树形的数据结构中,以便开发者通过对该树结构的节点进行增、删、改、查等操作的方式来实现Web应用程序用户界面的动态化。
第8章,DOM扩展与BOM。这一章介绍一系列具有专门用途的DOM扩展接口。通过使用这些接口,我们可以大幅度地降低开发、维护程序的成本,并提高程序的运行效率。本章还会介绍可用于在JavaScript脚本中执行浏览器相关操作的BOM接口。通过这些接口,我们可以在JavaScript脚本中完成页面的定位与导航、识别用户使用的浏览器、判断用户设备屏幕的大小、弹出系统对话框等任务。
第9章,前端事件处理。这一章详细介绍可用于响应用户界面操作的前端事件处理机制。首先对事件处理中所涉及的一些概念进行梳理,帮助读者了解何谓事件、如何触发事件、事件流是什么、如何响应事件等基础知识。然后从用户界面事件、鼠标操作事件、键盘操作事件以及焦点得失事件等几大类事件来介绍在Web应用程序的前端究竟可以处理哪些事件。除此之外,本章还会介绍事件在DOM事件流中的传播路径,它又分为事件捕获、处于目标与事件冒泡三个阶段,选择在哪一个阶段响应事件将在很大程度上决定事件处理函数的设计。
第10章,AJAX编程方法。这一章详细介绍AJAX编程方法。AJAX是一种让浏览器与服务器单独进行异步数据通信的方法,目的是让浏览器在不刷新当前页面的情况下与服务器进行数据交换,并根据交换的结果局部更新页面中的内容。首先介绍XMLHttpRequest对象提供的常用接口,以及用该对象进行异步数据通信的基本操作。然后介绍如何将XMLHttpRequest对象执行异步数据通信的基本操作后封装成常用的AJAX工具函数。除此之外,还会演示如何使用这些封装好的AJAX工具函数请求服务器端的数据。在此过程中,还会详细介绍JSON和XML这两种常用于网络传输的数据格式,演示如何在JavaScript代码中解析和序列化它们,并将请求到的数据在不刷新页面的情况下显示在页面中。
第11章,Node.js概述。这一章作为第三部分的开篇,会对Node.js这个可在浏览器之外运行JavaScript代码的运行环境进行概要性的介绍,为读者打好基础。
第12章,构建Web服务。这一章讨论如何在Node.js平台中构建Web服务。这是Node.js与PHP、JSP等Web应用开发方式的重大区别之一。使用PHP、JSP等应用开发方式通常需要借助Apache、Nginx、IIS这类服务器软件来构建Web服务,这无疑增加了Web全栈开发人员的学习成本和部署成本。当然,使用Node.js来构建Web服务也增加了编程的工作量。所以两种Web开发方式各有利弊,读者需根据自己的需要来取舍。
第13章,响应客户请求。这一章讨论如何编写基于Node.js的Web应用程序后端的核心任务:响应客户端请求。响应客户端请求的第一步是要对客户端发来的请求信息进行全面而细致的分析,这通常需要借助http.IncomingMessage类的实例来完成。本章首先会详细介绍该类对象常用的属性和方法,以及可以注册的事件处理函数。响应客户端请求的第二步是根据分析的结果构建要返回给客户端的响应数据。响应数据主要可分为静态数据与动态数据两大类,可以根据客户端请求的URL来区分它们。另外,在构建响应数据的过程中,通常需要借助fs模块中的方法将服务端的本地文件读取到程序中。若是静态资源就直接将读取出来的数据发送给客户端;若是动态资源,读取出来的数据必须进行一些处理才能发送给客户端,此时需要借助模板引擎构建响应数据。因此,本章也会对fs模块中的常用方法和模板引擎进行介绍。响应客户端请求的最后一步是将响应数据发送给客户端,这通常要借助http.ServerResponse类的实例来完成。本章会对该类对象常用的属性和方法,以及可以处理的事件进行详细介绍。
第14章,实现数据存取。这一章详细介绍如何在Web应用程序开发中解决数据持久化存取的问题。对于客户端,首先让人想到的是最传统的解决方案:Cookie。该方案虽然具有可自由配置数据有效时间、数据结构简单易用等优点,但也有大小非常有限、需要不断地在客户端与服务端来回传送、安全性不佳等缺点。为了解决Cookie方案存在的问题,HTML5提供了新的解决方案,即使用localStorage与sessionStorage这两个对象在客户端持久化存取不需要在客户端与服务端之间来回传送的数据。而对于服务端,数据存取操作通常需要借助数据库这种专用系统提供的解决方案来完成。本章会对这些解决方案进行逐一介绍。