JavaScript修炼之道(txt+pdf+epub+mobi电子书下载)

作者:聂常红 刘伟

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

JavaScript修炼之道

JavaScript修炼之道试读:

内容提要

本书分为基础知识、核心技术、高级应用和项目实战四部分。基础知识部分主要包括标识符、关键字和保留字、变量、数据类型、表达式和运算符、流程控制语句、在网页中嵌入JavaScript代码的三种方式以及程序调试方法等内容;核心技术部分主要包括数组、JSON、JavaScript函数、定时器、Math对象、Date对象、BOM对象、字符串、DOM模型、使用DOM操作HTML文档、使用JavaScript操作属性及元素内容、事件处理、正则表达式等内容;高级应用部分主要包括JavaScript面向对象及组件开发、Ajax编程等内容;项目实战部分介绍了一个使用HTML5+CSS3+JavaScript实现云盘的案例。

本书除了讲解JavaScript的基础知识外,还详细介绍了JavaScript的核心理论:变量提升、作用域链、原型链。本书最具特色的地方是提供了图片的切换、图片轮播、字符串查找与替换、选项卡、弹窗、上下文菜单、表单数据有效性校验、瀑布流布局、留言本等大量实用案例。

本书可作为从事网页设计、网页制作、网站建设、Web前端开发等工作的技术人员的学习用书,也可作为高等院校计算机及相关专业和培训机构的教材。

序言

在这个大多数人疯狂追求知识速成的时代,有些图书在宣传语中大肆渲染一个美妙的梦境:“朋友啊,一旦你拥有了本书,你只要花费极短时间,耗费极少精力,翻看几个篇章,甚至都不必深究或细读这些知识,便能系统透彻掌握JavaScript的所有奥秘。”可梦终归是要醒的,哪怕你总赖着不起床,冷冰冰的现实也会把你从白日梦中拽醒。越早告别天真,越早碾碎那些不切实际的想法,才能越快踏上成功之路。天道酬勤并非只是说说而已,那些每天比你多花几倍精力研究知识的人,如果不能比你获得更多,那么这个世界的运行规律就得改写了。

所以,这篇序言想表达的是:JavaScript这门语言并不容易学习。由于历史原因,这门语言虽然诞生已经有些年头了,但它本身那些令人困惑且逻辑不通的点,会变成你学习之路诸多障碍中的一部分。在深究底层原理的过程中,你得小心翼翼避开语言本身的各种陷阱,然后逐渐在大脑里构建一套稳固的知识体系。幸好,除了书之外,我们还提供了技术精湛的前端行业优秀的专家团队,在你需要的时候,通过本书的联系方式,我们将提供暖心的帮助,为你答疑解惑,甚至与你畅谈人生理想。

这篇序言还想告诉读者本书的特点和学习JavaScript的方法。

第一,本书重构了JavaScript语言体系。往前数十来年,前端开发者的学习征途异常坎坷。他们并非是没有学习方法的人,而是由于JavaScript的学习资料分散且极难考证。你可以在网上找到许多的“官方标准”,但实际运行时,大家还得看浏览器“脸色”行事,它们的“解释”若与你想的不一致,你辛苦写的代码执行结果就会很难堪。鉴于此,我们严格遵循实事求是的原则,从十多年企业一线开发实战经验出发,根据业务遭遇的种种“磨难”,重构了JavaScript学习体系,规避了学习中的深坑,确保按本书学习体系走下去的读者,学习之旅顺畅无比。即使碰到有些读者偏要往“深坑”里跳,也没关系,因为有我们的专家团队帮你答疑解惑,顺便把你拽出“深坑”。

第二,学习JavaScript语言,需要多敲代码+多思考+多练习。你当然可以把本书买来束之高阁,但我们并不希望如此。我们假定本书读者都能够理解:书只能为你系统地罗列一堆专业知识,并不能手把手教你要怎么学。我们思考的问题是:如何通过一本书教会你一套学习方法?如何才能成为学习方法的布道者?这既是摆在本书作者面前的难题,也是读者你最该思考的问题。我们想了又想,既要兼顾书的篇幅,又要摆事实、讲道理、教知识、给方法……哈,这真是太难了!想做好这些,绝不仅仅是在书里设置一些巧妙的课后练习、章节小贴士等就能解决的。幸好,我们的专家团队还能与你远程互动,甚至帮你探入某个工程,与你共修BUG。

第三,学习JavaScript切勿好高骛远。正所谓贪多嚼不烂,前端标准和工具这几年的飞速发展,以及时不时冒出的“新鲜玩意儿”让众多前端从业者惊呼:“学不动啦学不动啦!学习速度跟不上技术发展速度!我感到手忙脚乱、力不从心……”如果你有以上“症状”,请勿着急,这不过是你内心不安造成的。你为何追新?你又何苦追新?在根基不牢的情况下,就算盖楼盖到18层,再往上堆一块砖,都可能导致大楼坍塌!这结果绝非你预期。所以,此时你应该沉下心来苦练基础,而非死钻牛角尖。硬要及时掌握那些业界最新冒出来的“玩意儿”对你无益处,请读者朋友不必在意那些所谓的“新鲜知识点”在本书未涉及这一问题。事实上,绝大多数有必要的新东西本书都有写到,且书中所列皆是业界公认的经典基础知识。掌握了基础知识之后,剩下的就是提升编程能力了。而这些,只看书可实现不了。幸好,我们的专家团队能与你共同探讨“调试、算法、数据结构、操作系统、浏览器工作原理”等基础问题,妥妥地帮你摆平学习中的各种麻烦事儿。

好的书,是一位好“老师”。这本书可能不像你想象中那么好,但我们尽全力做的,是通过这本书,帮你结识前端技术牛人。他们在中国的前端发展历史中经历了一轮又一轮的技术洗礼,面对大厂技术迭代的狂风暴雨,他们愈战愈勇。更难能可贵的是,他们愿意把自己多年来的“爬坑”经验与更多人分享,例如他们如何严格地训练技能,如何心无旁骛地深入学习,如何获得学习反馈,怎样攻克复杂问题,怎样系统地训练自己编程、架构和工程能力……以上的这些专家团队、技术牛人,你都可以登录妙味课堂的官方网站寻找并与他们交流。

最后,我要感谢广州大学华软软件学院的聂常红老师,感谢她极为认真地参与本书架构体系的讨论、感谢她责任感十足地撰写书稿。这本书的出版承载了我们极大的期望,尽管我们尽力去编写,但书稿中难免有不妥之处,如果你在阅读时发现有任何问题,或不认同之处,请给我发邮件,我的邮箱是:leo@miaov.com,不胜感激。

学习是一种习惯,大家如果认同“日拱一卒、不期速成”,愿意相信“坚持的力量”并付诸行动,那么总有奇迹发生的那一天。大前端时代,大有可为。期待大家的进步!妙味课堂创始人开课吧合伙人IT学院院长刘伟2019年10月6日

第1章 JavaScript入门

JavaScript是一种解释型的脚本语言,被大量地应用于网页中,用以实现网页和浏览者的动态交互。目前几乎所有的浏览器都可以很好地支持JavaScript。由于JavaScript可以及时响应浏览者的操作,控制页面的行为表现,提高用户体验,因而已经成为前端开发人员必须掌握的语言之一。

1.1 JavaScript概述

JavaScript是为满足制作动态网页的需要而诞生的一种编程语言,是由Netscape(网景通信公司)开发的嵌入到HTML文件中的基于对象(Object)和事件驱动(Event Driven)的脚本语言。在HTML基础上,使用JavaScript可以开发交互式(网页)Web。JavaScript的出现使得网页和用户之间实现了实时、动态和交互的关系。1.1.1 JavaScript发展历史

JavaScript最初由Netscape的Brendan Eich开发,开发的目的是为了扩展即将于1995年发行的NetscapeNavigator2.0(NN2.0)功能,提高网页的响应速度。最初JavaScript叫作LiveScript,后来因为Netscape和Sun公司合作,且Java正处于强劲的发展势头中,出于市场营销的目的,Netscape和Sun公司协商后,将LiveScript改为JavaScript。当时的Microsoft(微软)为了取得技术上的优势,在IE3.0上发布了VBScript,并将其命名为JScript,以此来应对JavaScript。之后,为了争夺市场份额,Netscape和Microsoft这两大浏览器厂商不断在各自的浏览器中添加新的特性和各种版本的JavaScript实现。由于他们在实现各自的JavaScript时并没有遵守共同的标准,这就使得他们的浏览器对JavaScript的兼容性问题越来越大,从而给JavaScript开发人员带来巨大的痛苦。为了达到使用上的一致性,减轻JavaScript开发人员的痛苦,1997年,在ECMA(欧洲计算机制造商协会)的协调下,由Netscape、Sun、微软、Borland组成的工作组对JavaScript和JScript等当时存在的主要的脚本语言确定了统一标准:ECMA-262。该标准定义了一个名为ECMAScript的脚本语言,规定了JavaScript的基础内容,其中主要包括:语法、类型、语句、关键字、保留字、操作符和对象这几方面的内容。

从内容上看,ECMAScript规定了脚本语言的规范,而JavaScript、JScript等脚本语言则是依照这个规范来实现的,和ECMAScript相容,但包含了超出ECMAScript的功能。因为ECMA-262标准的出台,所以现在JavaScript、JScript和ECMAScript都通称为JavaScript(在后面的内容中,我们将会更多使用其简写“JS”来表示JavaScript)。浏览器的兼容性也越来越高:在2008年,五大主流Web浏览器(IE、Firefox、Safari、Chrome和Opera)就全部做到了与ECMA-262兼容;随着各大浏览器厂商的不断努力,特别是HTML5规范的发布,各大浏览器对JavaScript的兼容性也得到了不断的提高。依照这样的发展趋势,我们完全可以相信,不久的将来,各大浏览器必将实现对JavaScript的完全兼容。1.1.2 JavaScript组成部分及特点1.JavaScript组成部分

标准化后的JavaScript包含了3个组成部分,如图1-1所示。

ECMAScript:脚本语言的核心内容,定义了脚本语言的基本语法和基本对象。现在每种浏览器都有对ECMAScript标准的实现。图1-1 JavaScript组成部分

DOM(Document Object Model):文档对象模型,它是HTML和XML文档的应用程序编程接口。浏览器中的DOM把整个网页规划成由节点层级构成的树状结构的文档。用DOM API可以轻松地删除、添加和替换文档树结构中的节点。

BOM(Browser Object Model):浏览器对象模型,描述了对浏览器窗口进行访问和操作的方法和接口。2.JavaScript特点

JavaScript是一种运行在浏览器中的主要用于增强网页的动态效果、提高与用户的交互性的编程语言。相比于其他编程语言,它具有许多特点,主要包括以下几方面。(1)解释性

JavaScript不同于一些编译性的程序语言,它是一种解释性的程序语言,它的源代码不需要经过编译,直接在浏览器中运行时进行解释。(2)动态性

JavaScript是一种基于事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入直接做出响应。(3)跨平台性

JavaScript依赖于浏览器本身,与操作环境无关。任何浏览器,只要具有JavaScript脚本引擎,就可以执行JavaScript。目前,几乎所有用户使用的浏览器都内置了JavaScript脚本引擎。(4)安全性

JavaScript是一种安全性语言,它不允许访问本地的硬盘,同时不能将数据存到服务器上,不允许对网络文档进行修改和删除,只能通过浏览器实现信息浏览或动态交互。这样可有效地防止数据丢失。(5)基于对象

JavaScript是一种基于对象的语言,同时也可以被看作是一种面向对象的语言。这意味着它能运用自己已经创建的对象。因此,许多功能可以来自于脚本环境中对象的方法与脚本的相互作用。1.1.3 JavaScript与Java的区别

Java是由Sun公司开发的面向对象的程序设计语言,适合于网络应用程序开发。JavaScript最初是受Java启发而开始设计的,目的之一就是“看上去像Java”,因此语法上和Java有类似之处,一些名称和命名规范也源自于Java。但事实上,JavaScript除了在语法上和Java有些类似以及前面所说的出于市场营销的目的,名字和Java有点相似以外,其他方面和Java存在很大的不同,主要体现在以下几点。(1)JavaScript由浏览器解释执行,Java程序则是编译执行。(2)JavaScript是一种基于对象的脚本语言,其中提供了丰富的内置对象供开发人员直接使用;Java则是一种真正的面向对象的编程语言,不管开发的程序简单与否,都必须设计对象。(3)JavaScript是弱类型语言,声明变量时不需要声明变量的类型,甚至不声明变量而直接使用变量;Java是强类型语言,变量在使用前必须先声明且必须声明变量的类型。(4)代码格式及嵌入HTML文档方式不一样:Java代码必须用相应的编译工具编译为字节码文件,嵌入HTML文档必须使用标签嵌入字节码文件;JavaScript代码是一种文本字符格式,嵌入HTML文档使用标签,其中可以直接嵌入JavaScript代码,也可以嵌入JavaScript脚本文件。1.1.4 JavaScript语法特点及编辑工具

不管是JavaScript,还是Java、C++,它们编写的程序代码不外乎都是由一些英文单词按照一定的规则组织起来的一条条语句。这些语句遵循的各项规则,称为语法。JavaScript和Java、C++等编程语言的语法很类似,但它也具有自己的一些特点。1.区分大小写

和Java一样,JavaScript代码中的标识符也区分大小写,所以Student和student是两个不同的标识符,如果把student写成Student,程序将会出错或得不到预期结果。通常,JavaScript中的关键字、变量、函数名等标识符一般全部小写,如果名词是由多个单词构成,通常从第二个单词开始每个单词的首字母大写。2.语句结束的分号问题

不同于Java每条语句结尾必须加上分号,JavaScript语句结尾处的分号是可选的,即可加也可不加。如果语句结尾不加分号,JavaScript会对当前语句和下一行语句进行合并解析,如果不能将两者当成一个合法的语句来解析的话,JavaScript会在当前语句换行处填补分号,例如:var aa=3

解析的结果为var a;a=3;。

由JavaScript来添加分号在大多数情况下是正确的,但也有两个例外情况。第一个例外情况是涉及return、contiune和break这3个关键字的时候。不管什么情况下,如果这些关键字的行尾处没有分号,JavaScript都会对它们在换行处填补分号。例如,本意是return true;的语句,如果写成以下形式:return true;

则JavaScript解析后的结果将变成:return;true;。第二个例外情况是涉及“++”和“--”这两个运算符的时候。这些运算符既可作为表达式前缀使用,也可以作为表达式后缀使用。如果将其作为表达式后缀使用,它和表达式应该在同一行。否则,JavaScript将在行尾处填补分号。例如,本意是x++;y;的语句,如果写成以下形式:x++Y

则解析的结果为:x;++y;。

由前面两个例子可见,为了使语句不出现歧义,我们最好在每条语句的结尾处都加上分号。3.编辑工具

因为JavaScript代码是纯文本代码,所以可以使用任何文本编辑器来编辑JavaScript,甚至可以使用Microsoft Word这样的字处理软件,但此时一定要确保将文件保存为文本文件类型。建议最好使用以纯文本作为标准格式的软件。目前主流JavaScript编辑软件有:Dreamweaver、Visual Studio Code、Sublime Text、Atom和WebStorm。1.1.5 JavaScript的实际应用场景

很多其他语言的开发者或一些初学者对JavaScript的印象似乎停留在做各种“炫彩夺目的网站”上。的确,能够完成Web端复杂的交互,使得网页元素能够“动起来”,让信息以更佳效果呈现,这是JavaScript的功能之一;但它的实际应用场景远不止于此,一名专业前端开发工程师在工作中至少要使用JavaScript进行以下任务的开发。1.开发各种网页动态交互效果

在海量信息爆炸的时代,网站不仅要呈现必要的关键信息,还要以最佳方式与用户之间进行动态交互,加深用户对网站信息或功能印象,并提高用户体验和黏度。因此,更多网站的开发者们精心研发了某些表现力丰富的交互效果,例如以培训“前端开发”为主的妙味课堂官网,就在首页制作了一个形象的“展台”,并用动画堆叠的形式将前端必学的“HTML5\CSS3\JS”组合在一起,如图1-2所示,象征着学习前端开发最关键的基础语言是HTML5\CSS3\JS。图1-2 妙味课堂首页的交互展示效果之一2.使用Ajax等技术与后端进行数据交互

前端开发者每天要处理的大量编码工作中,占据很重比例的工作内容之一是根据后端提供的各种数据接口,把数据渲染到网页相应位置中,完成页面信息呈现。例如经典的登录和注册功能,当登录时会调用后端相应接口判断登录用户是否正确,而注册时会判断填写的用户名是否符合要求以及是否已被注册过。3.处理网页各种业务逻辑

在今天,许多内容型网站有大量用户关注,在这样的网站中,许多业务逻辑需要开发者使用JavaScript来实现。比如网站的使用者当中,有游客、普通会员,也有VIP会员,这几种不同类型的用户在权限上需要加以区分:游客、普通会员、VIP会员能观看的视频是不同的。在这样的需求下,网站内容展示需要根据不同的业务需求进行逻辑判断,这样才能在页面中呈现不同内容。这些功能,都需要开发者使用JavaScript做出判断处理。

除上述几个任务以外,JavaScript还可以变成运行在服务器上的后端开发语言(Node.js)以及能以Hybrid App形式运行在移动设备上的App开发语言。此外,还能够用来构建桌面应用、开发游戏、图形处理、PDF生成、编译解释器、测试工具、视频音频播放、通信……限于本书篇幅,在此不对这些展开介绍。

接下来,我们从最容易理解的“网页动态变化”原理开始与大家探讨,逐渐深入到JavaScript语言的学习中去。1.1.6 JavaScript实现网页动态变化原理以及执行顺序1.JavaScript实现网页变化原理

使用JavaScript后,可以实现许多网页的动态变化效果,诸如:跑马灯、选项卡切换、广告轮播、表单数据有效验证、漂移菜单、折叠菜单、倒计时等。这些动态变化效果的实现,并不需要网页重新加载,而是通过改变局部区域的外观或内容来实现。这正是JavaScript实现网页动态效果的原理。需要网页动态变化时,只需要根据变化的需要,使用JavaScript修改元素的样式或增加/清空页面元素内容或属性值。使用JavaScript动态改变网页时一般会结合CSS,其中CSS设置元素的初始样式,JavaScript则实现元素的动态样式。所以使用JavaScript实现网页动态效果,通常包含这样两个步骤:首先是使用CSS设置初始样式(即布局元素);然后再根据动态变化的需要,使用JavaScript修改元素样式或增加/清空页面元素内容或属性值。

JavaScript实现网页变化原理的应用示例请参见示例1-4。2.JavaScript代码执行顺序

JavaScript代码按照执行的机制可分为两类代码:事件处理代码和非事件处理代码。非事件处理代码如果不在某个函数中,则在载入HTML文档时,将按JavaScript在文档中出现的顺序,从上往下依次执行;如果非事件处理代码出现在某个函数中,则在调用该函数时执行。事件处理代码则在HTML文件内容载入完成,并且所有非事件处理代码执行完成后,才根据触发的事件执行对应的事件处理代码。3.JavaScript代码的调试

在编写JavaScript的过程中,很有可能会出现一些语法错误,所以在开发过程需要经常调试脚本代码(注:随写随调试不失为一种好习惯)。脚本代码的调试包括代码调试和工具调试两种方法,有关脚本代码的调试方法,我们将会在1.2节中详细介绍。

1.2 JavaScript代码的调试方法

开发人员在开发程序时,经常会碰到程序异常现象,要快速定位并解决程序异常,要求开发人员掌握一些常用的代码调试方法和调试工具。在JS代码中,最常用的调试方法是alert()方法和console.log()方法,而常用的调试工具则是IE浏览器的的“开发人员工具”、Firefox浏览器的“Firebug”工具(对较低版本的Firefox浏览器)或Firefox浏览器的“开发者>>Web控制台”(对较高版本的Firefox浏览器)以及Chrome浏览器的“开发者工具”。1.2.1 使用alert()方法调试脚本代码

在JS程序中常使用window对象的alert()方法进行代码跟踪或定位程序错误。alert()方法的作用是生成一个警告对话框,对话框中显示的信息由方法参数设定。alert()方法可以出现在脚本程序中的任意位置。alert()方法通过显示的变量值来跟踪代码,以及是否能显示警告对话框来定位错误。

alert()基本语法:方式一:alert(msg);方式二:window.alert(msg);

alert()方法是window对象的方法,在调用时可以通过window对象来调用,也可以直接调用。参数msg的值可以是任意值,当参数为非空对象以外的值时,警告对话框中显示的信息为参数值;当参数为非空对象时,在警告对话框中显示的是以[object object]格式表示的对象,其中第二个“object”会根据具体的对象来变化。例如,如果对象是一个表单输入框时,在对话框中将显示:[objectHTMLInputElement]。

需要注意的是,不同浏览器弹出的警告对话框外观不一样,比如对“alert("这些是警告对话框显示的信息")”这条代码,在Chrome浏览器(本书中示例的浏览器的版本主要为:Chrome73)中显示的警告对话框如图1-3所示,在Firefox浏览器中显示的警告对话框则如图1-4所示,在IE11浏览器中显示的警告对话框如图1-5所示。图1-3 Chrome浏览器中显示的警告对话框图1-4 Firefox浏览器中显示图1-5 IE11浏览器中显示的警告对话框的警告对话框【示例1-1】使用alert()方法调试代码。
使用alert()方法调试代码 累加结果:

注:示例代码中包含了多条JS代码。对这些代码的作用,我们现在不用过多关注,后面将会一一介绍到,目前大家只需要关注调试JS代码的方法就可以了。

上述代码在while循环语句中使用了两个alert()方法来分别跟踪sum变量和i变量的值,从显示的对话框的值我们可以看到这两个变量值的变化。另外在第二个script标签对之间也使用了alert()方法,这两个alert()方法主要是用来定位错误的。

上述代码在Chrome浏览器时,首先执行第一个标签对之间的JS代码块,该代码块主要处理一个循环语句,在第一次循环时会弹出图1-6所示的警告对话框,然后程序停止执行,直到单击了图1-6所示对话框中的“确定”按钮后才程序会继续执行,此时会弹出图1-7所示对话框,同样,如果不单击图1-7所示对话框中的“确定”按钮,程序也停止执行。可见,alert()具有阻塞程序执行的作用。

从运行结果中,可看到while循环语句总共执行了6次,每次都会弹出两个警告对话框分别显示变量sum和变量i的值。限于篇幅,在此,只显示了第一次循环的运行结果,其他循环的运行结果和图1-6、图1-7类似,所不同的是这两个变量的值不一样。

执行完第一个之间的JS代码块后,页面中显示表单输入框,接着执行第二个之间的JS代码块。结果只显示图1-8所示的警告对话框,即只有alert('111')执行了,alert('222')并没有执行。可见alert('111')和alert('222')之间的代码块有错误,导致程序无法往下执行。对该行代码进行检查后,发现倒数第6行“documnt”写错了,正确的写法是“document”。图1-6 第一次循环时显示的变量sum值图1-7 第一次循环时显示的变量i值图1-8 第二个script标签对之间的alert()输出结果

需要注意的是,用于调试代码的alert()方法在调试结束后要全部删掉。1.2.2 使用console.log()方法调试脚本代码

在JS中,除了使用alert()调试代码外,我们还常常使用console对象的log()对JS程序进行调试,console.log()方法的作用是在浏览器的控制台中输出指定的参数值。

需要注意的是,在一些较低版本的浏览器,比如IE6以及没装“Firebug”插件的较低版本的Firefox等浏览器中是不能使用console.log()的。现在IE11以及较新版本的Firefox和Chrome不用安装任何插件,都具备调试功能,对这些浏览器,window对象会自动注册一个名为console的成员变量,指代调试工具中的控制台。

console.log()的使用语法如下:console.log(msg);

log()方法的参数msg和alert()的参数用法一样,也可以是任意值;但当参数为非空对象时,不同于alert()输出的是[object object]格式的内容,log()的输出内容包含对象的结构内容。

就调试作用来说,alert()和console.log()方法类似,但相比于alert(),使用console.log()是一种更好的方式,原因如下。(1)alert()会阻塞JS程序的执行,不单击“确定”按钮,后续代码无法继续执行;而console.log()仅在控制台中打印相关信息,不会阻塞JS程序的执行。(2)对于输出内容为对象时,console.log()输出的对象能看到对象结构;而alert()则是以[object object]格式输出对象,无法看到对象结构。【示例1-2】使用console.log()方法调试代码。
使用console.log()方法调试代码累加结果:

上述代码在Chrome浏览器中执行后,同时按“Ctrl+Shift+I”组合键(对Mac苹果电脑使用的是Command+Option+I组合键),打开Chrome浏览器的“开发者工具”,默认将打开“Console”浏览器控制台,在控制台中查看各个console.log()的输出结果,可看到图1-9所示的结果。刷新图1-9所示页面,可看到几乎在控制台显示结果的同时,也显示了表单输入框,可见console.log()不会阻塞JS程序的执行。图1-9 console.log()的输出结果1.2.3 使用Chrome的“开发者工具”调试脚本代码

对JS程序的调试,除了在JS程序中使用alert()、console.log()方法跟踪和调试代码外,开发人员也会经常使用一些调试工具。最常用的JS调试工具就是一些主流的浏览器的调试工具,如IE11浏览器的“开发人员工具”、Firefox浏览器的“Firebug”工具或较新版本的“开发者>>Web控制台”以及Chrome浏览器的“开发者工具”。限于篇幅的原因,本节将只介绍Chrome浏览器的“开发者工具”调试工具,IE浏览器的“开发人员工具”和Firefox浏览器的“Firebug”以及“开发者>>Web控制台”工具的使用和Chrome浏览器的“开发者工具”类似,大家可参考Chrome浏览器的“开发者工具”来使用它们。

相对于使用alert()方法来定位错误,使用调试工具会更便捷高效。因为调试工具可以在控制台具体指出出错的代码行数,以及具体的错误类型。此外,还可以使用控制台直接运行JS代码。接下来我们将通过示例1-3的JS代码的的调试来介绍Chrome的“开发者工具”的使用。【示例1-3】使用Chrome的“开发者工具”调试代码。
使用调试工具调试代码累加结果:1.调试定位错误

在Chrome浏览器中运行示例1-3,当没有得到预期结果时,使用调试工具会比较容易定位错误。操作步骤为:同时按“Ctrl+Shift+I”组合键,打开Chrome浏览器的“开发者工具”,此时在默认打开的“Console”控制台可以看到显示出错代码行及错误类型,如图1-10所示。图1-10 在控制台中显示错误信息

图1-10报引用错误,说文件ex1-3.html中的第9行代码中的“documnt”没有定义,根据这个错误信息,我们很容易发现原来这个单词写错了,正确的写法是“document”。2.跟踪调试代码

使用调试工具,同样也可以跟踪变量的变化,步骤如下。(1)修改图1-10所报错误后,将“开发者工具”中的选项卡切换到“Sources”,将打开一个包含3个窗口的界面,在左侧的窗口中双击文件“ex1-3.html”,此时会在中间窗口中打开源代码,如图1-11所示。图1-11 打开源代码(2)对代码添加断点。对代码设置断点的方法是:在需要添加断点的那个代码行的行号处单击鼠标左键,此时该行行号会显示蓝色背景,如图1-12所示。(3)设置断点后刷新页面,此时根据需要可单击右侧的调试窗口中的这3个按钮中的其中一个或按这3个按钮对应的快捷键F10、F11和Shift+F11,分别实现逐句(F10)、逐过程(F11)和跳出(Shift+F11)这3种调试情况。在调试过程中,我们可以在右侧的调试窗口中的“Local”项中跟踪每一个变量在运行过程中的取值情况,如图1-13所示。

注:单击右侧调试窗口中的按钮,或同时按“Ctrl+\”组合键或按“F8”快捷键可以停止代的码调试。3.使用控制台运行JS代码

打开Chrome浏览器,打开“开发者工具”的控制台,然后在控制台窗口光标所在位置输入JS代码或按“Ctrl+V”组合键复制JS代码,然后按“Enter”键回车即可运行控制台中的JS代码,如图1-14所示。图1-12 设置断点图1-13 跟踪调试代码图1-14 在控制台中运行JS代码

注:控制台中会默认输出JS代码中最后一个变量的值,如图1-14中的最后一个“6”就是最后的变量i的值。

1.3 第一个JavaScript实例

在进一步介绍JavaScript之前,我们首先看一个JavaScript实例。通过这个实例,我们将陆续引入一些知识点。在本节,我们不会详细介绍这些知识点,它们的详细介绍请参见相应章节。此处引入它们的目的是为了让大家了解这些知识点的大致概念,这样后续各章节在介绍这些知识点时不会太突兀。

示例1-4的功能是:初始状态显示一个宽度和高度都为200px,且背景颜色为灰色的div;当将光标移到div上时div的宽度变为400px,背景颜色变为粉红色;当将光标从div上移出时div的宽度和背景颜色都恢复为初始样式。

通过分析可知,上述功能包含两种效果:一是初始效果,二是动态效果。由此我们可以按照1.1.5小节所介绍的使用JavaScript实现网页动态变化效果的步骤来实现上述功能需求:初始效果可以使用CSS来设置,而光标移入、移出所产生的动态效果则使用JavaScript来实现。具体代码如下所示。【示例1-4】第一个JavaScript实例。
第一个JavaScript实例

上述代码在Chrome浏览器中运行后的初始效果和光标移出div后的效果完全一样,如图1-15所示,光标移入div后的效果如图1-16所示。图1-15 初始效果和光标移出div后的效果图1-16 光标移入div后的效果

示例1-4使用CSS代码获得图1-15所示的初始效果,包括设置div的宽度、高度和背景样式。而图1-16所示的效果,以及由图1-16恢复到图1-15所示的效果则使用JavaScript代码来实现。这些JavaScript代码在示例中通过标签嵌入到HTML页面中。浏览器加载HTML文档的过程中,一遇到就会调用JavaScript引擎对脚本代码进行解析和执行。

注:JavaScript引擎,简单地说,就是能够“读懂”JavaScript代码,并准确地给出代码运行结果的一段程序。JavaScript引擎是浏览器的一个组成内容,一般由各个浏览器开发商自行开发,所以不同浏览器的JavaScript引擎有可能是不同的,比如:IE的JavaScript引擎是Chakra、Chrome的JavaScript引擎是V8等。在早期,JavaScript引擎可以说就是一个解释器,但现在的JavaScript引擎其实都具有了一些编译器的功能,比如Chrome的JS引擎V8,为了提高JS的运行性能,在运行之前会先将JS编译为本地的机器码码,然后再去执行机器码,这样速度就快很多。

示例1-4中脚本代码到目前为此,对初学者来说还很陌生,下面我们将对它们进行一一讲解。

上述代码中以“//”开头的语句表示注释语句。注释语句的作用是对代码进行描述说明。注释语句主要是给开发人员和维护人员看的,目的是为了提高代码的可读性和可维护性。浏览器对注释语句既不会显示,也不会执行。在JavaScript中,注释有单行注释和多行注释两种形式。所谓单行注释,就是注释文字比较少,在一行内可以显示完;多行注释就是注释文字比较多,需要分多行来显示。多行注释也可以用多个单行注释来表示。单行注释以“//”开始,后面跟着的内容就是注释,示例1-4中的注释全部都是单行注释;多行注释以“/*”开始,以“*/”结束,它们之间的内容就是注释,示例如下:/* 第一行注释文字 第二行注释文字 …… */

注释①对应的代码:用于获取文档中指定id的元素,并将元素储存在指定的变量中,其中的“var”用于声明变量,var后面跟着的单词就是变量名。因为状态动态变化是通过修改特定元素的样式来实现的,另外,光标的移入和移出也是针对特定的元素的,所以必须首先获取这些特定元素。获取文档中的特定元素最常用的方法是使用document对象或其他文档元素对象调用getElementById(元素id属性值)方法。由于getElementById()方法需要使用id值,所以对应的元素中必须包含id属性。

注:获取文档元素除了可以使用getElementById(),还有其他一些常用的方法,如getElementsByTagName('标签名'),这个方法将会返回指定标签名的所有元素,结果是一个数组,这些方法我们将会在后续章节中陆续介绍。

注释②和④处的代码:分别表示光标移入和光标移出div的事件处理。在JavaScript中,光标移入和光标移出分别表示两个事件(所谓事件,就是用户与Web页面交互时产生的操作。而在Web页面中产生事件的对象,称为事件目标),这些事件一旦发生,将会由事件目标调用相关的脚本代码进行处理。例如,用户将光标移到和移出div元素时,会分别触发光标移入和光标移出事件,此时事件目标是div元素。注释②处的代码通过事件目标调用changeStyle函数来处理光标移入事件;注释④处代码则通过事件目标调用resetStyle函数来处理光标移出事件。在JavaScript中,除了上述示例中的光标移入和光标移出事件外,还有许多事件,例如键盘事件、表单事件、窗口事件等,对这些事件及其处理我们将在第9章详细介绍。

注释⑦和⑧处的代码:分别定义了两个函数,函数名分别为changeStyle和resetStyle。所谓函数,其实就是实现某种功能的一系列命令(即脚本代码)的集合。在JavaScript中,定义函数的语法格式是:function 函数名([参数列表]){ 命令1; 命令2; … }

function为函数定义的关键字,不能省略;函数名可以任意命名或使用函数表达式时可以直接省略函数名,命名时名称需要符合规范;参数可以包含0到多个,不管参数有没有,小括号都必须保留;函数中的所有命令必须放到一对大括号中。需要注意的是,函数定义后,不会自动执行,必须通过调用,函数才可以执行。函数的调用方式有多种,常用方式有:直接调用函数以及事件调用。事件调用需要在脚本代码中将函数名或函数定义作为元素的事件属性值,所以这种调用方式也称为事件绑定。事件绑定的函数在事件发生时会自动执行,事件没发生则不会执行。需要注意的是,使用函数名来绑定事件时,函数名后面不能跟小括号,否则,代码执行到函数名所在行时事件没有发生也会自动调用函数执行。示例1-4中的函数调用代码分别如注释②和④处所示,它们都使用了事件绑定方法,将changeStyle和resetStyle两个函数分别绑定到了onmouseover和onmouseout事件,这样一旦发生光标移入事件和光标移出事件就会调用相应的函数。有关函数的调用及其他内容我们将在第4章详细介绍。

注释③和⑥处的代码在此作为调试代码使用,alert()的作用是弹出警告对话框。当我们将注释④处的代码用“//”注释起来,同时将注释③、⑤和⑥处的代码前面的“//”删掉,然后再次运行示例1-4,结果只弹出图1-17所示的警告对话框,由此可知③处的代码执行了,但⑥处的代码没有执行,因此可以判断,③处代码前面的代码都没有问题,但③和⑥之间的⑤处的代码有问题。经检查,原来把定义的函数名“resetStyle”写成了“resetStyl”。

除了可以使用alert()方法调试脚本,还可以使用浏览器的“开发者工具”调试。打开Chrome浏览器的“开发者工具”,在默认打开的控制台窗口,可以看到图1-18所示的错误信息。图1-17 执行alert("hi")后弹出的警告对话框图1-18 Chrome浏览器“开发者工具”控制台的报错信息

图1-18所示的错误信息提示ex1-4.html文件中的第26行代码的“resetStyl”没有定义。可见,使用“开发者工具”同样可以很容易得知错误所在地方。

在前面的介绍中,我们说事件绑定既可以使用函数名,也可以使用函数定义,这两种方式的作用是完全一样的,所以我们可以将示例1-4注释②和④处的函数调用进行如下修改://使用函数定义绑定事件 oDiv.onmouseover = function changeStyle(){ oDiv.style.width = "400px"; oDiv.style.background = "#FCF"; }; //使用函数定义绑定事件oDiv.onmouseout = function resetStyle(){ oDiv.style.width = "200px"; oDiv.style.background = "#CCC";};

很显然,通过绑定函数定义可以使代码更加简洁。不过,绑定函数定义有一个条件,就是该函数只需要绑定到一个事件上。如果一个函数需要绑定在多个事件上,则需要使用示例1-4所示的方法,即将函数名绑定到事件。一个函数只需要绑定在一个事件上时,我们还可以通过省略函数名进一步简化代码,此时可将上述代码修改为如下代码://使用没有函数名的函数定义绑定事件 oDiv.onmouseover = function (){ //使用匿名函数 oDiv.style.width = "400px"; oDiv.style.background = "#FCF"; };//使用没有函数名的函数定义绑定事件 oDiv.onmouseout = function (){ //使用匿名函数 oDiv.style.width = "200px"; oDiv.style.background = "#CCC";};

上述代码中,没有函数名的函数称为匿名函数,相对应的,有函数名的函数称为有名函数。从前面的介绍可知,当一个函数需要在多处调用时,需要使用有名函数;如果只需要在一个地方调用,则建议使用匿名函数,这样可以使代码更加简洁。

在示例1-4中,我们看到

在Chrome浏览器运行上述代码,结果和图1-15、图1-16所示完全一样。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书

若在网站上没有找合适的书籍,可联系网站客服获取,各类电子版图书资料皆有。

客服微信:xzh432

登入/注册
卧槽~你还有脸回来
没有账号? 忘记密码?