JavaScript忍者秘籍(第2版)

978-7-115-47326-4
作者: 【美】John Resig(莱西格) Bear Bibeault(贝比奥特) Josip Maras(马瑞斯)
译者: 郭凯一心一译前端小组
编辑: 陈冀康

图书目录:

详情

本书分设计、构建和维护3个阶段介绍全新的JavaScript开发技术。首先让读者建立牢固的基本知识,然后讲解如何构建JavaScript库,解释了构建JavaScript库需要应付和解决的问题的解决方案和开发策略,还介绍了保证代码运行良好的维护技术。

图书摘要

版权信息

书名:JavaScript忍者秘籍(第2版)

ISBN:978-7-115-47326-4

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。

• 著    [美] John Resig Bear Bibeault Josip Maras

  译    一心一译前端小组

  责任编辑 陈冀康

• 人民邮电出版社出版发行  北京市丰台区成寿寺路11号

  邮编 100164  电子邮件 315@ptpress.com.cn

  网址 http://www.ptpress.com.cn

• 读者服务热线:(010)81055410


Original English language edition, entitled Secrets of the JavaScript Ninja,Second Edition by John Resig, Bear Bibeault and Josip Maras published by Manning Publications Co., 209 Bruce Park Avenue, Greenwich, CT 06830. Copyright ©2016 by Manning Publications Co.

Simplified Chinese-language edition copyright ©2018 by Posts & Telecom Press. All rights reserved.

本书中文简体字版由Manning Publications Co.授权人民邮电出版社独家出版。未经出版者书面许可,不得以任何方式复制或抄袭本书内容。

版权所有,侵权必究。


JavaScript语言非常重要,相关的技术图书也很多,但至今市面没有一本对JavaScript语言的最重要部分(函数、闭包和原型)进行深入、全面介绍的图书,也没有一本讲述跨浏览器代码编写的图书。而本书弥补了这一空缺,是由jQuery库创始人编写的一本深入剖析JavaScript语言的书。

本书共分4个部分,从不同层次讲述了逐步成为JavaScript高手所需的知识。本书从JavaScript语言及最重要的特性谈起,由浅入深地探讨了函数、作用域、闭包、生成器函数、对象、数组、模块化、JavaScript与Web页面的交互以及事件等主题,引导读者更加深入地了解JavaScript的方方面面,充分展示了JavaScript语言的各种特性。本书结合ECMAScript 6和7的相关概念,涵盖了流行的JavaScript框架所使用的技术。

本书适合具备一定JavaScript基础知识的读者阅读,也适合从事程序设计工作并想要深入探索JavaScript语言的读者阅读。


一心一译前端小组是一群热爱前端和JavaScript的技术人员,他们因兴趣而走到一起,致力于为读者奉献高品质的中译版技术图书。

郭凯

美团点评酒旅事业群前端团队负责人,高级技术专家,资深互联网人,全栈工程师,工作狂,崇尚工匠精神,曾就职于音悦台、淘宝旅行。译作有《编写可维护的JavaScript》《第三方JavaScript编程》《JavaScript开发框架权威指南》,有In、Juicer、jSQL、F2E.im、PM25等开源项目,业余时间负责开源前端技术社区F2E的开发和维护。

赵荣娇

前端开发工程师,也是《响应式设计、改造与优化》一书的译者。著有《超实用的CSS代码段》《代码逆袭:超实用的HTML代码段》等书籍。喜欢旅行,热爱前端开发。

王思可

北京大学在校学生,热爱JavaScript,热爱技术。

巩守强

猫眼基础交易负责人,美团前端高级技术专家,对于前端工程化、前端性能优化和客户端动态化感兴趣。

康明轩

北京师范大学硕士,现就职于北京指南针科技发展股份有限公司,从事网络应用开发,认为编程也是一门可以长相厮守的手艺。


John Resig 是可汗学院(Khan Academy)的一名资深工程师,是jQuery JavaScript库的创建者,也是《JavaScript忍者秘籍(第1版)》和《精通JavaScript》的作者。

John开发了日本版画综合性数据库和图片搜索引擎:Ukiyo-e.org。他是美国和日本艺术学会的董事会成员,也是立命馆大学(Ritsumeikan University)的客座研究员,致力于研究浮世绘。

Bear Bibeault 编写软件已经超过30年,刚开始是通过100波特的电传打字机在控制数据网络超级计算机上编写井字程序。Bear有电气工程双学位,本应从事设计天线之类的技术工作,但自从他在数字设备公司从事第一份工作起,他就更着迷于编程。Bear还分别在 Dragon Systems、Works.com、Spredfast、Logitech、Caringo等诸多公司工作过。Bear目前是一名高级前端开发工程师,在一家对象存储软件的领先供应商工作,提供可伸缩性的海量存储和内容保护服务。

除了本书的第1版,Bear也是其他一些 Manning 书籍的作者,包括《jQuery实战》(第1版、第2版、第3版),《Ajax实战》《原型脚本实战》。他也是O’Reilly出版社出版的“Head First”系列书籍的审稿人,例如《Head First Ajax》《Head Rush Ajax》和《Head First Servlets and JSP》。

除了日常工作外,他还经营着一家小型企业,致力于创建Web应用程序,为其他媒体提供服务,并作为“引领者”(超级管理员)管理CodeRanch.com。

Josip Maras是克罗地亚斯普利特大学电气工程学院、机械工程学院、造船建筑学院的博士后研究员。他获得软件工程博士学位,论文题目是“在Web应用程序开发中实现自动复用”,其中包括使用JavaScript实现的JavaScript解释器。在他的研究中,他已经出版了十多篇科学会议和期刊论文,主要是分析客户端Web应用程序的处理程序。

不做研究时,他从事教学工作,教授学生网站开发、系统分析和设计、Windows开发等知识(过去6年培养了几百位学生)。他还拥有一个小型软件开发公司。


参与编写本书的人数之多会让你们感到吃惊。天才们的共同努力付出带来了此刻你捧在手里的这本书(或在屏幕上阅读的电子书)。

Manning 出版社的工作人员不知疲倦地帮助我们确保本书的质量,感谢他们的付出。没有他们,本书不可能完成。包括出版人Marjan Bace、编辑Dan Maharry,还有以下贡献者们:Ozren Harlovic、Gregor Zurowski、Kevin Sullivan、Janet Vail、Tiffany Taylor、Sharon Wilkey、Alyson Brener和 Gordan Salinovic。

感谢本书的审阅者们,从简单细致的排版到术语的纠正以及代码中的错误修正,再到组织本书的章节,他们每一轮的审阅,对本书最终出版的质量都有很大的提高。非常感谢他们花时间审阅本书:Jacob Andresen、Tidjani Belmansour、Francesco Bianchi、Matthew Halverson、Becky Huett、Daniel Lamb、Michael Lund、Kariem Ali Elkoush、Elyse Kolker Gordon、Christopher Haupt、Mike Hatfield、Gerd Klevesaat、Alex Lucas、Arun Noronha、Adam Scheller、David Starkey和 Gregor Zurowski。

特别感谢Mathias Bynens 和 Jon Borgman,他们对本书提供技术校对。除了在多种环境中逐一校对书中的每一个示例代码,他们还对本书的技术准确性提供了非常重要的指导意见,他们找到初始版本已经遗失的信息,快速同步了浏览器上对JavaScript与HTML5的最新变化。

感谢我的父母多年来对我的支持和鼓励。他们为我提供了很多有用的资源和工具,激发我对编程的兴趣——他们一直都鼓励着我。

首先要特别感谢 coderanch.com(JavaRanch)的工作人员。如果不加入CodeRanch,我就不会有机会开始参与写作本书,我衷心感谢 Paul Wheaton 和 Kathy Sierra让我开始这项工作,以及以下同事对我的鼓励和支持,包括(但不限于):Eric Pascarello、Ernest Friedman-Hill、Andrew Monkhouse、Jeanne Boyarsky、Bert Bates和 Max Habibi。

感谢我的伴侣Jay忍受我参与这项工作时,只专注于浏览器和缺乏打字技术的胖手指。除了抱怨一下糟糕的Word、某个浏览器或者任何使我愤怒的事之外,我几乎很少从键盘上抬起头来。

最后,感谢我的合著者John Resig和Josip Maras,没有他们就没有这本书。

最大的感谢献给我的妻子——Josipa,感谢她忍受我将大量时间投入到本书的写 作中。

还要感谢Maja Stula、Darko Stipanicev、Ivica Crnkovic、Jan Carlson 和 Bert Bates:感谢他们的指导和有用的建议,以及在本书截止日期之前对我的包容。

最后,感谢我的家人——Marijas、Vitomir和Zdenka——感谢你们的陪伴。


自2008年我编写《JavaScript忍者秘籍》起,到现在JavaScript的世界发生了翻天覆地的变化。我们现在编写的JavaScript,虽然大部分仍然是基于浏览器,但是几乎快认不出来了。

由于功能全面、跨平台的特性,JavaScript的流行度呈爆发式增长。Node.js是一个强大的平台,人们已基于Node.js开发了无数的生产应用程序。开发人员实际上是在使用一种语言——JavaScript编写应用程序以及同时可运行于浏览器端、服务器端甚至移动设备上的本地应用。

现在所需的JavaScript知识,比以前任何时候都更为重要。对JavaScript这门语言有一个基本的理解,并且了解最佳编程方式,有助于创建几乎可在任何平台运行的应用程序,几乎没有其他语言可以做到这一点。

与以往JavaScript增长的时代不同,平台不兼容的情况没有得到改善。你常常会垂涎于使用最基本的浏览器新特性,但是过时的浏览器却占领了太多的市场份额。我们已经进入了一个和谐的时间,大多数用户都在快速更新最符合标准的平台。浏览器厂商甚至推出专门针对开发人员的特性,希望这能使他们的生活更加简单。

浏览器目前提供给我们的工具以及开源社区,是过去实践之后的光明。我们现在有大量的可供选择的测试框架,有持续集成测试的能力,可以生成代码覆盖报告,在真正的全球移动设备上做性能测试,甚至可在任何平台上自动加载虚拟浏览器进行测试。

这本书的第1版极大地受益于Bear Bibeault 的开发洞察力。这个版本得到Josip Maras大量的帮助,他研究ECMAScript 6和7的相关概念,深入了解测试最佳实践,了解流行的JavaScript框架所使用的技术。

我们编写JavaScript的方式发生了巨大的变化,这很难阐述。好在这本书可以帮助你了解当前的最佳实践。不仅如此,本书还会帮助你改善思维方式,如何将开发实践作为一个整体,以确保为未来编写JavaScript。

John Resig


JavaScript非常重要。过去并非如此,但现在的确如此。如今JavaScript已经成为最重要的、使用最广泛的编程语言。

Web应用程序为用户带来了丰富的用户界面体验,如果没有JavaScript,可能只能显示小照片。Web开发人员比以往任何时候都更需要熟练掌握JavaScript语言,JavaScript 为 Web 应用程序注入了生命。

JavaScript不再只应用于浏览器了。JavaScript打破了浏览器的界限,可应用于服务端的Node.js,可应用于桌面设备和移动设备如Apache Cordova,甚至可内置在设备中如 Espruino和Tessel。虽然本书主要集中介绍在浏览器端执行JavaScript,但本书介绍的JavaScript基础适用范围非常广泛。深刻理解概念、了解多种技巧有助于你成为全栈JavaScript工程师。

随着使用JavaScript的开发人员逐渐增多,熟练掌握JavaScript基础比以往任何时候都更加重要,这样才能成为真正的JavaScript“忍者”。

如果你不熟悉JavaScript,那么这本书并不适合作为你的第一本JavaScript图书。但也别太担心,我们试图介绍基本的JavaScript概念,对于初学者也相对容易理解。但是,本书更适合于至少掌握JavaScript基础、了解JavaScript代码执行的浏览器环境,并且希望深入理解JavaScript语言的Web开发人员。

本书通过4个部分,让你从“学徒”晋升为“忍者”。

第1部分介绍我们后续学习的主题和所需要的工具。

第2部分重点关注JavaScript的核心支柱之一——函数。我们将研究为什么函数如此重要,函数之间的区别,以及定义和调用函数的细节内容。我们还将特别关注一个新的函数类型——生成器函数,它在处理异步代码时尤为有效。

第3部分研究JavaScript的第二支柱——对象。我们将彻底地探索JavaScript中的面向对象,研究如何保护对对象的访问,如何处理集合和正则表达式。

最后,第4部分研究JavaScript与Web页面的交互以及浏览器如何处理事件,最后结束本书。在结束之前的最后一个重要话题是跨浏览器开发。

代码清单或文本中的所有源代码都采用等宽字体,与普通文本进行区分。

在某些情况下,为了适应页面,会对源代码进行格式化。一般来说,编写源代码时需要考虑页面宽度限制,但有时你会发现本书中的代码和下载的代码之间的格式有所不同。在极少数情况下,为了不改变代码的含义,代码过长无法被格式化,本书的代码清单中使用行连续符号进行标记。代码注释和许多列表用于突出重要概念。

本书中示例的源码清单(以及一些未在文本出现的其他代码)可以在本书的网页 https://manning.com/books/secrets-of-the-javascript-ninja-second-edition或异步社区(www. epubit.com.cn)下载。

本书的示例代码按章节分类,每一章为一个文件夹。文件夹排列顺序由本地Web服务器完成,如Apache HTTP 服务器。将下载的代码解压缩到所选择的文件夹,并将该文件夹设置为应用程序的根目录。

除了少数示例外,大多数示例不需要Web服务器,如果需要,可以直接加载到浏览器中执行。

本书作者和 Manning 出版社邀请读者访问本书的论坛,该论坛由 Manning 出版社直接运营,在论坛上你可以评论本书、询问技术问题,并获得作者和其他读者的帮助。在浏览器上登录 https://manning.com/books/secrets-of-the-javascript-ninja-second-edition,访问并订阅论坛,然后单击作者在线链接。作者在线页面提供关于如何注册并登录论坛,可以获得哪些帮助,以及论坛行为规则等相关信息。

Manning 承诺为读者提供一个读者与作者能够进行有意义交流的场所。Manning 不强制要求作者的参与次数,对本书论坛的贡献仍然是自愿的(无报酬)。我们建议读者尝试询问一些有挑战性的问题,以免作者丧失兴趣!

本书在售期间,在线交流论坛和先前发布的讨论帖都可以在出版商的网站上访问。


《JavaScript忍者秘籍》(第2版)封面上的图像是“能乐剧(Noh)演员,武士”,是19世纪中期一位不知名的日本艺术家制作的木刻版画。能乐剧(Noh)衍生自日语天赋和技能,是从14世纪开始出现的一种经典音乐剧。许多人物都戴着面具,男性同时扮演男性和女性的角色。作为日本数百年来的英雄人物,武士经常在表演中出现。在本书封面中,精致的服装和威武的雄姿展示了这位艺术家的精湛技艺。

武士和“忍者”都是日本艺术作品中善于打斗的勇士,他们都非常勇敢和精明。武士是精英士兵,受过良好教育,文武双全。战争时,武士们穿着精致的盔甲和彩色的服装,震慑对方。“忍者”则是通过武术技能筛选,而不是依仗社会地位或受教育水平。“忍者”们身着黑色服装,蒙面,单独行动或小组出动,以诡计或隐身攻击敌人,千方百计地完成任务。他们的代号唯一,并且保密。

封面插图是Manning出版社的一位编辑多年来收集到的三个日本人物版画中的一个。当我们在为本书寻找“忍者”封面时,这幅引人注目的武士版画吸引了我们,该版画细节精致、色彩鲜明,生动地描绘出一位威武的武士志在必得的决心。

有时很难区分不同的计算机图书。Manning非常有创意,使用200年前的版画作为计算机图书的封面,这些插画描绘世界各地丰富多彩的传统服装,将其印刷在封面上,带来新的活力。


模板字面量(template literal)是允许嵌入表达式的字符串字面量: '${ninja}'

块级作用域变量:

函数参数:

function multiMax(first,...remaining){/*...*/}multiMax(2,3,4,5);//first: 2;
      remaining: [3, 4, 5]
function do(ninja,action="skulk"){return ninja+" "+action;} 
do("Fuma");//"Fuma skulk"

扩展语法(spread operator)允许一个表达式在期望多个参数(用于函数调用)或多个元素(用于数组字面量)或多个变量(用于解构赋值)的位置扩展:[...items,3,4,5]

箭头函数(arrow function)可以创建语法更为简洁的函数。箭头函数不会创建自己的this参数,相反,它将继承使用执行上下文的this值:

const values = [0, 3, 2, 5, 7, 4, 8, 1];
values.sort((v1,v2)=> v1 - v2);/*OR*/ values.sort((v1,v2) => {return v1 - v2;});
value.forEach(value => console.log(value));

生成器(generator)函数能生成一组值的序列,但每个值的生成是基于每次请求,并不同于标准函数那样立即生成。每当生成器函数生成了一个值,它都会暂停执行但不会阻塞后续代码执行。使用yield来生成一个新的值:

function *IdGenerator(){
  let id = 0;
  while(true){ yield ++id; } 
} 

promise对象是对我们现在尚未得到但将来会得到值的占位符。它是对我们最终能够得知异步计算结果的一种保证。promise既可以成功也可以失败,并且一旦设定好了,就不能够有更多改变。

通过调用传入的resolve函数,一个promise就被成功兑现(resolve)(通过调用reject则promise被违背)。拒绝一个promise有两种方式:显式拒绝,即在一个promise的执行函数中调用传入的reject方法;隐式拒绝,如果正处理一个promise的过程中跑出了一个异常。

myPromise.then(val => console.log("Success"),err => console.log("Error"));

(Class)是JavaScript原型的语法糖:

class Person {
 constructor(name){this.name = name; }
 dance(){return true; }
}
class Ninja extends Person {
 constructor(name, level){
   super(name);
   this.level = level;
 }
 static compare(ninja1, ninja2){ 
   return ninja1.level - ninja2.level;
 } 
}

代理(Proxy)可对对象的访问进行控制。当与对象交互时(当获取对象的属性或调用函数时),可以执行自定义操作。

const p = new Proxy(target, {
  get:(target, key) => { /*Called when property accessed through proxy*/ }, 
  set: (target, key, value) => { /*Called when property set through proxy*/ }
});

映射(Map)是键与值之间的映射关系:

集合(Set)是一组非重复成员的集合:

for...of循环遍历集合或生成器。

对象与数组的解构(destructuring):

模块(Module)是更大的代码组织单元,可以将程序划分为若干个小片段:

export class Ninja{}; //导出Ninja类
export default class Ninja{} //使用默认导出
export {ninja};//导出存在的变量
export {ninja as samurai}; //导出时进行重命名

import Ninja from "Ninja.js"; //导入默认值
import {ninja} from "Ninja.js"; //导入单个导出
import * as Ninja from "Ninja.js"; //导入整个模块的内容
import {ninja as iNinja} from "Ninja.js"; //导入时重命名单个导出


本书的第1部分将为你奠定JavaScript“忍者”修炼的基础。在第1章中,我们将一览JavaScript的现状,并探讨几种能够运行JavaScript代码的环境。作为JavaScript的“发祥地”,浏览器将是我们的重点关注对象。此外,我们还将讨论一些JavaScript应用开发中的最佳实践。

由于我们对JavaScript的探索限定在浏览器中,因此我们在第2章中介绍了客户端网络应用的生命周期以及JavaScript代码的执行过程与该生命周期的对应关系。

当你读完这部分之后,就可以开始JavaScript“忍者”的修炼了。


本章包括以下内容:

我们先来聊聊Bob。2000年年初,在花了几年时间学习C++桌面应用开发之后,新晋程序员Bob从学校毕业,奔向了软件开发的广阔天地。那个时候,互联网的跨越式发展才刚刚开始。每个公司都想成为下一个亚马逊。有鉴于此,他做的第一件事就是学习网络开发。

最初他用PHP动态生成网页,并在其中穿插JavaScript代码来实现复杂的功能,例如表单验证,甚至是动态的页内计时器。时光如梭,几年之后,智能手机已然成了气候。预见到一个庞大的新兴市场即将形成,Bob决定先行一步,开始学习使用Objective-C和Java来创建运行于iOS和Android上的移动端应用。

几年来,Bob开发了很多成功的应用软件,并且都需要维护和扩展。遗憾的是,日日辗转于不同的编程语言和应用框架之间,可怜的Bob已经筋疲力尽了。

现在我们来谈一下Ann。两年前,Ann在获得软件开发相关的学位后毕业。她的专业方向偏向于网络以及基于云的应用开发。她已经开发出了一些中等规模的网络应用。这些应用基于现代的模型—视图—控制器(Model—View—Controller, MVC)框架,并且还有相应的移动应用供iOS和Android用户使用。她还开发了一款能够同时在Linux、Windows和OS X上运行的桌面应用,甚至着手将其改为完全基于云的无服务器的版本。最重要的是,她所做的所有事情都是通过JavaScript来实现的

真是一件了不起的事情。Bob花了10年用5种语言才完成的事情,Ann只需要2年以及1种语言就完成了。纵观整个计算机的发展史,还没有哪个特定的知识集合能够如此容易地通行于不同的领域,并发挥作用。

1995年的一项10天内仓促完成的项目,现在却成为了世界上使用最广泛的编程语言之一。JavaScript现在确确实实是无处不在了,这得归功于更强大的JavaScript引擎和一众框架的出现,如Node、Apache Cordova、Ionic和Electron,是它们让这门粗陋的语言冲出了网页的牢笼,飞向了更广阔的空间。此外,如同HTML一样,这门语言本身也正处于期待已久的进化当中,从而被打造成更加适合现代应用开发的语言。

在本书中,我们首先要保证让你了解所有你需要了解的关于JavaScript的内容,这样无论你的情况与Ann还是Bob更为接近,都能够开发各种类型的应用。

你知道吗

随着职业生涯的发展,许多有着与Bob和Ann类似经历的JavaScript程序员,都到了在工作中运用构成这门语言大部分的元素的阶段。但实际上,很多时候这些技能的运用都处于相当初级的层次。我们对此做出的猜测是,由于JavaScript(采用类似于C语言的语法)有着与其他得到广泛使用的类C语言(比如C#和Java)相近的皮相,从而给人留下了与这些语言相似的印象。

人们总是觉得他们对C#或者Java的了解,能为他们理解JavaScript的工作原理打下坚实的基础。然而这是一个陷阱。与其他主流语言相比,JavaScript函数式语言的血统更多一些。JavaScript中的一些概念从根本上不同于其他的语言。

这些根本性的差异包括以下内容。

对象、原型、函数和闭包的紧密结合组成了JavaScript。理解这些概念的密切联系能大大提高你的编程能力,为你开发各种类型的应用提供坚固的基础,无论你的应用是开发在网页上、桌面应用上、移动应用上还是服务器端。

除了这些基本概念,JavaScript的一些其他功能也能帮你书写优雅高效的代码。对于经验老道的Bob一样的开发者来说,这些部分特性在其他语言中也出现过,例如Java和C++。我们会特别聚焦于以下特性。

深入理解JavaScript的基础知识,以及学习如何最大程度地利用JavaScript的高级特性,能够让你的代码编写水平提升到一个更高的水平。磨炼代码技能、并将这些概念和特性连贯起来也能让你对JavaScript的理解更上一层楼,从而为你编写各种类型的Javscript应用赋予强大的创造力。

ECMAScript语言标准化委员会已经完成了ES7/ES2016版本JavaScript的制定。对于JavaScript(至少相对于ES6而言)ES7是个较小的升级。这是因为委员会的未来目标是每年都能为JavaScript更新较小的改动。

本书中将彻底探索ES6以及ES7的新特性,例如用于处理异步代码的async函数(第6章中会讨论)。

注意

 

在本书中涉及ES6/ES2015或ES7/ES2016的JavaScript特性时,你将能看到,凡是在提供浏览器是否支持该特性的链接旁边都会有一个这样的图标。

尽管每年都能增量发布语言新特性是个利好消息,但这并不代表Web开发者能在标准一发布就能立即使用新特性。由于JavaScript代码必须由JavaScript引擎来执行,所以我们必须耐心等待心爱的引擎更新,从而能支持那些令人激动的新特性。

尽管JavaScript引擎开发者也在力求始终保持对最新特性的支持,但开发者还是很可能陷入想使用新特性却还没被支持的困境。

好在你还能通过下列方式https://kangax.github.io/compat-table/es6/、http://kangax. github. io/compat-table/es2016plus/以及 https://kangax.github.io/compat-table/esnext/进行查看,由此保持对浏览器支持状态的了解。

由于浏览器版本的飞速发布,我们通常不需要等待多久就能等到对JavaScript的支持。但当我们想利用JavaScript的最新特性时,也往往会被残酷的现实绑架:用户依然在使用老旧的浏览器。这时该怎么办?

解决这个问题的方式之一是使用转换编译器transpilers(即“转换器+编译器”,“transformation + compiling”),这类工具能够把最前沿的JavaScript代码转换为等价的(如果不能实现,则使用相似的)能在当前浏览器中运行的代码。

最流行的转换编译器是Traceur和Babel。使用如下教程可以很容易地配置它们:https://github.com/googLe/traceur-compiler/wiki/Getting-stanted或http://babeljs.io/docs/setup。

本书中,我们会主要集中讨论浏览器中的JavaScript代码。为了有效利用浏览器平台,你需要多多实践,学习浏览器的内部原理。让我们开始吧!

现如今,JavaScript应用能在很多环境中执行。但是,Java Script最初的运行环境是浏览器环境,而其他运行环境也是借鉴于浏览器环境。本书将重点专注浏览器环境。浏览器提供了多种概念和API让我们来探索,如图1.1所示。

图1.1 客户端Web应用依赖于浏览器提供的架构。我们主要讨论DOM、
事件、计时器和浏览器API

我们将集中讨论如下概念。

近来浏览器的质量已经大大提高了,但我们仍然需要面对一些缺陷:例如缺失的API、某个浏览器的奇怪问题。针对浏览器的这些问题开发出一种易于理解的机制,并搞清楚它们的差异和宽松模式,这与精通JavaScript几乎同等重要。

当我们开发浏览器应用或JavaScript库时,选择支持哪个路蓝旗是很值得深思熟虑的。我们希望全部支持,但受限于开发测试资源要求或其他要求。因此在第14章中,我们将彻底地探索跨浏览器开发的策略。

开发高效的跨浏览器代码显著依赖于开发者的经验和技巧。本书旨在提高开发者技能水平,所以让我们通过当前的最佳实践来开始学习吧。

精通JavaScript语言和掌握跨浏览器代码问题对于专家级Web应用开发者来说是重要课题,但它们不是整个蓝图。若想进入整个联盟,你还需要展示出一些已经被大量先前开发者所证明能够开发出高质量代码的特质。这些特质被称为最佳实践,所以你除了精通JavaScript语言以外,还需要具有以下特质:

在编程中把这些技能有效结合在一起非常重要,本书会使用它们。接下来看看这些技巧。

以前,调试JavaScript代码意味着使用alert来验证变量的值。好在,由于Firefox浏览器的开发者扩展Firebug的流行,所以调试JavaScript代码的能力大大增强了。所有主流浏览器的类似工具也都被开发出来:

如你所见,主流浏览器都为开发者提供了调试Web应用程序的工具。使用alert来调试JavaScript代码的日子一去不复返了!所有这些工具都有着类似于Firebug最初引入的概念,故而它们都提供着相似的功能:探索DOM、调试JavaScript、编辑CSS样式和跟踪网络事件等。其中的每样工具都做得很棒。你既可以使用你自己选择的浏览器所提供的调试工具,也可以使用你发现缺陷时所用的浏览器调试工具。

除此之外,你也可以使用其中的几个工具,例如用Chrome开发者工具来调试其他类型的应用,例如 Node.js应用(在附录B中,我们会向你介绍一些调试技术)。

在本书中,我们会使用一些测试技术来确保示例代码按预期执行,同时这些测试技术也用于展示一般情况下如何测试代码。我们用于测试的主要工具是一个断言函数,其目的在于断定某个假设是真值还是假值。

该函数的一般形式如下所示:

assert(condition, message);

第一个参数是一个应为真值的条件,第二个参数是当断言为假时所展示的一句话。

例如:

assert(a === 1, "Disaster! a is not 1!");

如果变量的值不等于1,则断言失败,然后那段有点儿戏剧性的消息就会被展示出来。

注意

 

断言函数并不是JavaScript的标准特性,所以我们在附录B中会展示它的实现。

分析性能是另一个重要实践。尽管JavaScript引擎已经让JavaScript以惊人的效率提升,然而我们依然没有理由书写粗糙低效的代码。

我们会使用如下的代码来收集性能信息:

console.time("My operation");  ←--- 开始计时器

for(var n = 0; n < maxCount; n++){
  /*perform the operation to be measured*/
}  ←--- 执行多次操作

console.timeEnd("My operation");  ←--- 停止计时器

这段代码中,我们把要被测量的代码放在两个计时器调用之间,分别是内置console对象上的time和timeEnd方法。

在操作开始执行之前,调用console.time启动一个命名计时器(本例中计时器名为 My operation)。然后在特定的循环次数下运行代码(本例中运行maxCount次)。由于一次操作执行太快很难测量,所以我们要多次运行代码从而取得一个能够测量的值。运行次数可以成百上千,甚至上万,其完全依赖于将被测量的代码性质。几次摸索后我们就能得到一个合理的值。

操作结束后则用相同的计时器名字调用console.timeEnd。随后浏览器就会输出从开始到当前的时间差。

把这种技术与前面所学到的最佳实践技术统一起来,你对JavaScript的开发能力就会大幅度提升。在浏览器提供的有限资源下,在浏览器能力和兼容性逐渐复杂的世界中开发应用,需要一套健壮和完整的技巧。

Bob初入Web开发行业时,他会发现每个浏览器都有一套自己的脚本及UI样式的解释方式,并试图鼓吹他们的方式才是最好的方式,这使开发者们沮丧地咬牙切齿。好在浏览器之争以HTML、CSS, DOM、API和JavaScript的标准化而结束,从而开发者能集中精力开发高效的跨浏览器JavaScript应用。确实,集中精力于把网站开发为应用催生了大量的想法、工具和从桌面应用到网站应用的技术。现如今,这些知识和工具的转换再次发生,想法、工具和源于客户端Web开发的技术逐渐渗入应用开发的其他领域。

对JavaScript基本原理和核心API的渗入理解能让你成为更全能的开发者。通过使用浏览器和Node.js(源自于浏览器的环境),你能够开发几乎你能想到的任何类型的应用。

Ann并不知道自己有多幸运(尽管Bob有个很棒的想法)。无论她是否需要构建一个标准的桌面应用还是移动应用、服务器端应用或嵌入式应用都没问题——所有这些应用都共享同样的标准客户端Web应用底层原理。

只要理解了JavaScript工作的核心原理、理解了浏览器提供的核心API(例如事件,同样与Node.js提供的机制有很多共同点),她就能加速所有应用的开发。在这个过程中,你将变得更全能,知识和理解力也逐步增长,从而能够处理各种各样的问题。你将能够在云上通过使用JavaScript API构建无需依赖服务器的应用,例如使用类似AWS Lamda来部署、维护和控制你应用的云组件。


相关图书

HTML+CSS+JavaScript完全自学教程
HTML+CSS+JavaScript完全自学教程
JavaScript面向对象编程指南(第3版)
JavaScript面向对象编程指南(第3版)
JavaScript全栈开发
JavaScript全栈开发
HTML CSS JavaScript入门经典 第3版
HTML CSS JavaScript入门经典 第3版
HTML+CSS+JavaScript网页制作 从入门到精通
HTML+CSS+JavaScript网页制作 从入门到精通
JavaScript重难点实例精讲
JavaScript重难点实例精讲

相关文章

相关课程