JavaScript启示录(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-25 18:07:38

点击下载

作者:[美]Cody Lindley(著)

出版社:人民邮电出版社

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

JavaScript启示录

JavaScript启示录试读:

前言

简介

本书无关于JavaScript设计模式,也无关于JavaScript面向对象代码实现。本书的写作目的也不是鉴别JavaScript语言特点的好坏。本书并不是一本完整的参考指南。它面向的读者人群并不是编程新手或对JavaScript完全陌生的人员。同时,它也不是一本JavaScript攻略手册。关于上述这些方面的书籍都已经面世。

本书的撰写意图是通过考察原生JavaScript对象和不同环境对原生对象的支持的细微差别,来给读者展现准确的JavaScript世界观:复杂值、原始值、作用域、继承、head对象等。我希望本书是关于ECMAScript第三版规范的简单易懂的总结,重点介绍JavaScript中对象的特性。

如果你是只使用过JavaScript库(如jQuery、MooTools、Zepto、YUI、Dojo等)的设计师或开发人员,我希望本书中的资料能够使你从JavaScript库用户转变成为JavaScript开发人员。为什么要写这本书?

首先,我必须承认,写这本书是为了我自己。说实话,精心编制这些资料,这样我就可以品尝自己制作的“饮品”,并始终记得它的“味道”。换句话说,我想用自己的语言来编写参考书籍,以便在需要时用来唤起我的记忆。另外:● JS库会导致“黑匣子”综合征,它对某些方面是有益的,但对

某些方面是不利的。有些事情完成得很快速和高效,但你却不知

道如何或者为何要如此。当事情不顺利或性能成为问题时,如何

以及为何就显得很重要了。事实上,在构建Web应用程序时(或

只是一个优秀的注册表单),如果想要实现JavaScript库或框

架,就应该打开“引擎盖”看看,了解“发动机”的情况。本书

就是写给那些想要打开JavaScript这个“引擎盖”并不怕弄脏手

的人的。● Mozilla提供了最新和最完整的JavaScript 1.5参考指南。我认为现

在缺少的是一个从单一角度编写的易读文档,从而配合他们的参

考指南使用。希望本书会成为JavaScript方面的指南,告诉你“你需要知道什么”,并详述一些Mozilla指南未涉及的概念。● 虽然JavaScript 1.5版本发布了很长一段时间,ES6和ES5中的新

特性固然要用,但我们希望将存在时间较久的有关JavaScript基

础概念撰写成书。● 有关编程语言的高级技术书籍通常都有大量的代码示例和无意义

的漫谈。我更喜欢用直接切中要点的简短解释,使用可以立即运

行的真实代码。我发明了一个新词“技术性薄片撷取(technical

thin-slicing)”,来描述我在本书中想要使用的东西。这就需要将

复杂的主题精简为更小、更易读的概念,并采用最少的词汇以及

全面、精准的代码示例。● 大多数值得一读的JavaScript书籍都有3英寸厚。像David

Flanigan等人所写的权威指南肯定有它们自己的一席之地,但我

想要编写的书籍只专注于重要的内容,而不详述所有知识。谁应该阅读本书?

本书面向两种人群。第一种是希望通过深入了解JavaScript对象来巩固对语言理解的高级初学者或中级JavaScript开发人员。第二种是准备研究JavaScript幕后知识的JavaScript库使用老手。本书不适合编程新手、JavaScript库使用新手以及JavaScript开发新手。为什么是JavaScript 1.5和ECMAScript第3版?

在本书中,我重点介绍的是JavaScript 1.5版本(相当于ECMAScript第3版),因为它是到目前为止实现最为广泛的JavaScript版本。本书的下一版肯定会转向日渐重要的ES6和ES5版本。为什么没有涉及Date()、Error()和RegEx()对象?

正如前面所说的,本书不是关于JavaScript的详尽参考指南,相反,本书致力于将对象作为了解JavaScript的透镜。因此,我决定在书中不涉及Date()、Error()和RegEx()对象,尽管这些对象都很有用,但是掌握这些对象的细节内容对JavaScript对象的总体理解不会产生很大的影响。我希望大家能够将在这里所学到的知识应用到JavaScript环境中可用的所有对象中。

在开始学习本书之前,了解本书所采用的各种模式是非常重要的。请不要跳过本节,因为它包含一些有助于阅读本书的重要信息。多代码,少文字

请仔细检查代码示例。应将文本视为仅次于代码本身的内容。我认为一个代码示例胜过一大堆文字。不要担心刚开始对一些解释感到困惑。检查代码,研究代码,重读一遍代码注释,重复这个过程,直到清晰了解所解释的概念。你最好有一定的专业知识,这样你只需要有良好文档记录的代码就可以深刻理解编程概念。详尽代码与反复

你可能会讨厌我老是重复,以及使用了如此全面的代码示例。我可能会受到埋怨,但我宁可要精确、详细和反复,而不像有的作者常常把错误假设提供给读者。是的,不管将要引入的知识是什么,详细和反复都有可能令人厌烦,但它们对于那些想详细学习某一主题的人来说仍是很有用的。编码约定

在JavaScript代码示例中(如下例所示),粗体用于突出显示与所讨论概念直接相关的代码。任何用来支持粗体代码的其他代码都将用正常文本表示。 jsFiddle、JS Bin和Firebug lite-dev

本书中的大多数代码示例都有相应的jsFiddle页面链接(http://jsfiddle.net),可以调整和在线执行代码。jsFiddle示例已经配置使用了Firebug lite-dev插件(http://fbuggooglecode.com/svn/lite/branches/firebug1.3/content/firebug-lite-dev.js),以便无论浏览器是否有自己的控制台,日志功能(即console.log)都能够在大多数现代浏览器中工作。在阅读本书之前,要确保自己可以接受console.log的用法和目的。

如果使用jsFiddle和Firebug lite-dev导致JavaScript代码复杂,则会将JS Bin(http://js-bin.tumblr.com/about)和Firebug lite-dev组合使用。我试图通过使用Firebug lite-dev来避免产生对浏览器控制台的依赖,但该解决方案本身的相关代码示例会阻碍代码执行。在这些情况下,就不得不利用构建到Web浏览器中的控制台来输出日志。如果不想使用有内置JavaScript控制台的浏览器,我建议升级或切换浏览器(http://brousehappy.com)。

使用JS Bin时,要记住的是,必须要手动执行代码(单击Render),因为这不同于由jsFiddle执行的页面加载。本书约定

本书使用下列排版约定(参照编码约定(P3)):

斜体(Italic)

表示第一次出现的专业词汇、链接(URL)、电子邮件地址、文件名和文件扩展名。

等宽字体(Constant width)

表示广义上的程序清单,包括变量或函数名、数据库、数据类型、环境变量、语句和关键字。

等宽粗体(Constant width bold)

表示应该由用户逐字输入的命令或其他文本。

等宽斜体(Constant width italic)

表示应该由用户提供的值或取决于上下文的值。这个图标表示提示、建议或一般说明。这个图标表示警告或提醒。代码示例

这本书是为了帮助你做好工作。一般来说,可以在你的程序和文档中使用本书的代码,无须联系我们获取许可。例如,使用本书中的几段代码写一个程序是不需要许可的;出售和散布O’Reilly书中用例的光盘(CD-ROM)是需要许可的;通过引用本书用例和代码来回答问题是不需要许可的;在你的产品文档中引用本书中大量的用例代码是需要许可的。

我们赞赏但不强求注明信息来源。一条信息来源通常包括标题、作者、出版者和国际标准书号(ISBN),例如,“JavaScript Enlightenment by Cody Lindley (O’Reilly). Copyright 2013 Cody Lindley, 978-1-449-34288-3”。

如果你感到对示例代码的使用超出了正当引用或这里给出的许可范围,请随时通过permissions@oreilly.com联系我们。®Safari在线图书Safari在线图书(Safari Books Online:www.safaribooksonline.com)是一家按需服务的数字图书馆,提供来自世界领先作者的技术类和商业类专业参考书目和视频。

专业技术人员、软件开发人员、Web设计师、商业和创意专家将Safari 在线图书作为他们研究、解决问题、学习和认证培训的主要资源。

Safari 在线图书为组织、政府机构和个人提供一系列的产品组合和定价计划。用户可以在一个来自各个出版社的完全可搜索的数据库中访问成千上万的书籍、培训视频和正式出版前的手稿。这些出版社包括:O’Reilly Media、Prentice Hall Professional、Addison-Wesley Professional、微软出版社、Sams、Que、Peachpit Press、Focal Press、Cisco Press、John Wiley & Sons、Syngress、Morgan Kaufmann、IBM Redbooks、Packt、Adobe Press、FT Press、Apress、Manning、New Riders、McGraw-Hill、Jones & Bartlett、Course Technology等。欲获得有关Safari 在线图书的更多信息,请在线访问我们。联系我们

如果您对本书有意见和问题,请联系出版社:

美国:

O’Reilly Media, Inc.

1005 Gravenstein Highway North

Sebastopol, CA 95472

中国:

北京西城区西直门南工街2号

成铭大厦C座807室(100035)

奥莱利技术咨询(北京)有限公司

我们已将本书做成一个网页,我们在那里列出了勘误表、示例及其他信息。您可以打开网址http://oreil.ly/javascript_enlightenment访问这个页面。

如需对本书发布评论或提出技术问题,请发送电子邮件至bookquestions@oreilly.com。

欲获知有关我们的图书、课程、会议及新闻的更多信息,请访问我们的网站http://www.oreilly.com。

Facebook网址:http://facebook.com/oreilly

Twitter网址:http://twitter.com/oreillymedia

YouTube网址:http://www.youtube.com/oreillymedia 第1章JavaScript对象1.1 创建对象

在JavaScript中,对象为“王”:JavaScript里的几乎所有东西都是对象或者用起来像对象。理解了对象,就能够理解JavaScript。因此,让我们来查看一下JavaScript中的对象创建。

对象只是一组有命名值(也称为属性)集合的容器。在阅读JavaScript代码之前,让我们先来推理一下。以我自己为例,我们可以用简单的语言在表格中表达“cody”:codyproperty:property value:livingtrueage33gendermale

上述表格中的“cody”一词只是一组属性名和所对应值的标签,这些属性和值构成了cody。正如表格中所看到的:我还活着,33岁,男性。

然而,JavaScript不会用表格来表达,它是用对象来表达的,就像“cody”表格中包含的那样。将上述表格转化成实际的JavaScript对象应是这样的:Fiddle地址:http://jsfiddle.net/javascriptenlightenment/ckVA5/

最重要的是要记住:对象只是属性的容器,每个属性都有一个名称和一个值。JavaScript采用具有命名值属性的容器(即对象)这一概念作为在JavaScript中表达值的构建块。cody对象是一个值,通过创建对象将这个值表示为JavaScript对象,给对象命名,然后将属性赋值给对象。

到目前为止,我们所讨论的cody对象只有静态信息。鉴于正在研究JavaScript编程语言,我们希望为cody对象编写代码,做一些真正有意义的事情。不然,也就只有一个类似JSON(http://www.json.org/)的数据库。为了使cody对象有生命力,需要添加一个属性:方法(method)。方法用于执行函数(function)。确切地讲(http://bclary.com/2004/11/07/%23a-4.3.3),在JavaScript中,方法是包含Function()对象的属性,其目的是对函数内部的对象进行操作。

更新cody表格,加入getGender方法,用浅显的英语表示如下:codyproperty:property value:livingtrueage33gendermalegetGenderreturn the value of gender

用JavaScript代码表示,更新后的上述“cody”表格中的getGender方法应是这样的:Fiddle地址:http://jsfiddle.net/javascriptenlightenment/3gBT4/

getGender方法是cody对象的属性,用于返回cody的其他属性值:存储在gender属性中的"male"值。必须知道的是,如果没有方法,除了用于存储静态属性以外,对象就没有其他太多用途。

截至目前,我们讨论的cody对象是一种Object()对象。通过使用调用Object()构造函数而得到的空对象创建了cody对象。将构造函数视为模板或饼干模具来生成预定义对象。对于cody对象示例,使用Object()构造函数来生成空对象,然后将它命名为cody。鉴于cody是由Object()构造函数构造出的一个对象,所以将cody称为Object()对象。大家真正需要了解的是,除了创建像cody这样简单的Object()对象外,JavaScript中的大多数值都是对象("foo"、5和true等原始值例外,但它们拥有等效包装器对象)。

由Object()构造函数创建的cody对象与通过string()构造函数创建的字符串对象没有太大的区别。为了证明其真实性,可检验和对比下面的代码:Fiddle地址:http://jsfiddle.net/javascriptenlightenment/XcfC5/

正如这里所显示的,myObject和myString都是对象!它们都可以有属性、继承属性,并且都由构造函数生成。包含"foo"字符串值的myString变量看似很简单,但令人惊讶的是,在其表面之下有一个对象结构。查看生成的这两个对象,你会发现这两个对象虽然在本质上是相同的,但在类型上是不同的。更重要的是,希望你开始了解,JavaScript是使用对象来表示值的。注意看到字符串值采用"foo"对象形式,你可能会觉得很奇怪,因为通常字符串在JavaScript中被表示为原始值(如var myString = 'foo';)。我在这里特地用一个字符串对象值来强调所有的东西都可以是对象,包括通常不将其视为对象的值(即字符串、数字、布尔值)。同时,我认为这有助于解释为什么有些人说JavaScript中的所有东西都可以是一个对象。

JavaScript将String()和Object()构造函数作为其自身的语言,以便使String()对象和Object()对象的创建变得简单。但是作为JavaScript程序员,也可以创建同样强大的构造函数。如下代码,定义了一个非原生的自定义Person()构造函数,以便用它创建people对象。Fiddle地址:http://jsfiddle.net/javascriptenlightenment/zQDSw/

用户自定义的Person()构造函数可以生成person对象,就像原生String()构造函数可以生成字符串对象一样。Person()构造函数的能力和延展性并不比原生String()构造函数或JavaScript中的其他原生构造函数差。

还记得我们开始看到的cody对象是如何从Object()生成的吗?重要的是要注意,在上个代码示例中的Object()构造函数和new Person()构造函数可以产生相同的结果。两者都可以生成具有相同属性和属性方法的相同对象。查看下面两段代码,结果表明,尽管生成方式不同,codyA和codyB却拥有相同的对象值。Fiddle地址:http://jsfiddle.net/javascriptenlightenment/Du5YV/

codyA和codyB对象之间的主要区别不在于对象本身,而是在于生成对象的构造函数。codyA对象是使用Object()构造函数实例来产生的。Person()构造函数创建了codyB,但也可以把Person()构造函数当成一个强大的、集中定义的对象“工厂”,用于创建更多的Person()对象。为自定义对象创建自定义构造函数的同时,也为Person()实例创建了原型继承。

这两个方案都能够创建相同的复杂对象。这两个模式最常用于构造对象。

JavaScript实际上是一种预包装若干原生对象构造函数的语言。这些构造函数用于生成一些表达特定类型值(如数字、字符串、函数、对象、数组等)的复杂对象,同样,也可以通过Function()对象创建自定义的对象构造函数(例如Person())。不管是否是用于创建对象的模式,产生的最终结果通常都是创建一个复杂的对象。

理解对象的创建、本质、用法以及其原始等价代码是本书其余部分的重点。1.2 JavaScript构造函数构建并返回对象实例

构造函数的作用是创建多个共享特定特性和行为的对象。构造函数主要是一种用于生成对象的饼干模具,这些对象具有默认属性和属性方法。

如果说“构造函数只是一个函数”,那么我会说“你是对的,除非使用new关键字来调用该函数。”(如new String('foo'))。如果使用new调用某函数,该函数则担任一个特殊的角色,JavaScript给予该函数特殊待遇,将该函数的this值设置为正在构建的新对象。除了这个特殊行为,该函数还默认返回新创建的对象(即this),而不是虚假值。该函数返回的新对象则被认为是构建该对象的构造函数的实例。

再次思考Person()构造函数,但这一次要仔细阅读下面代码中的注释,因为其内容强调了new关键字的作用。Fiddle地址:http://jsfiddle.net/javascriptenlightenment/YPR6Q/

上述代码利用了自定义构造函数(即Person())来创建cody对象。这与Array()构造函数创建Array()对象(如new Array())没有什么不同:Fiddle地址:http://jsfiddle.net/javascriptenlightenment/cKa3a/

在JavaScript中,大多数值(不包括原始值)都涉及正在被创建的对象,或者是从构造函数实例化的对象。构造函数返回的对象被称为实例。读者要熟悉这些语义,同样要熟悉利用构造函数来构建对象的模式。1.3 JavaScript原生/内置对象构造函数

JavaScript语言包含9个原生(或内置)对象构造函数。JavaScript使用这些对象来构建JavaScript语言。“构建”的意思是指,这些对象是用于表达JavaScript代码中的对象值,以及协调语言中的多个特性。因此,原生对象构造函数是多方面的,它们生成对象,但也被用于促进语言的编程约定的形成。例如,函数是Function()构造函数创建的对象,但作为构造函数,使用new关键字调用后,它们也可用于创建其他对象。

下面列出了JavaScript预包装的9个原生对象构造函数:● Number()● String()● Boolean()● Object()● Array()● Function()● Date()● RegExp()● Error()

JavaScript主要是由这9个对象(以及字符串、数字和布尔原始值)来创建的。深入理解这些对象,对充分利用JavaScript独特的编程力量和语言灵活性是非常关键的。注意● Math对象在这里是很古怪的。它是一个静态对象,而不是构造函数,也就是说,我们不能这么做:var x = new Math()。但我们可以使用它,就好像它已经实例化好了一样(如Math.PI)。实际上,Math只是一个由JavaScript设置的对象命名空间,用于存储数学函数。● 原生对象有时也被称为“全局对象”,因为它们是JavaScript中原生就可以使用的对象。不要混淆的术语是拥有"head"全局对象的global object(全局对象),它是作用域链中的最高层级。例如,所有Web浏览器中都有的window对象。● Number()、String()和Boolean()构造函数不仅能够构建对象,而且能为字符串、数字和布尔值提供原始值,这取决于如何充分利用构造函数。如果直接调用这些构造函数,那么就会返回一个复杂对象。如果只是简单地在代码中表示一个数字、字符串或布尔值(5、“foo”和true等原始值),那么构造函数将返回一个原始值,而不是一个复杂的对象值。1.4 用户自定义/非原生对象构造函数

正如在Person()构造函数中所看到的,我们可以创建自己的构造函数,从中可以生成不只一个,而是多个自定义对象。

下面列出了熟悉的Person()构造函数:Fiddle地址:http://jsfiddle.net/javascriptenlightenment/GLMr8/

正如你所看到的,通过传递特定的参数和调用Person()构造函数,可以轻松地创建大量的特定people对象。当需要两个或三个以上具有相同属性但具有不同值的对象时,这样做是非常有用的。细想一下,这正是JavaScript使用原生对象所发挥的作用。Person()构造函数与Array()构造函数一样也遵循同样的原则。因此new Array('foo','bar')与new Person(true, 33, 'male')确实没有多大差异。创建自定义构造函数只是在使用JavaScript本身在原生构造函数中所使用的相同的模式。注意● 虽然这不是必需的,但当创建将要与new操作符一起使用的自定义构造函数时,最佳做法是保持构造函数名称的第一个字符大写:是Person(),而不是person()。● 关于构造函数比较复杂的一点就是this值在函数内部的使用方式。请记住,构造函数只是一个饼干模具,在将它与new关键字一起使用时,它会创建一个拥有构造函数内部定义的属性和值的对象。在使用new关键字时,this值的字面意思是基于构造函数内部的语句创建的新对象/新实例。另一方面,如果创建一个构造函数,且不使用new关键字进行调用,那么this值将引用包含该函数的“父”对象。更多细节内容请参考第6章。● 可以放弃使用new关键字和构造函数的概念,方法是使该函数显式地返回一个对象。必须显式地编写构建并返回Object()对象的函数:var myFunction = function(){return {prop: val}};。但是,这样做会避开原型继承的使用。1.5 使用new操作符实例化构造函数

构造函数从根本上说是用于创建预配置对象的饼干模具模板。以String()为例,这个函数在与new操作符[new String('foo') ]一起使用时会创建基于String()模板的字符串实例。让我们来看一个示例。Fiddle地址:http://jsfiddle.net/javascriptenlightenment/FKdsp/

上述代码创建了一个新的字符串对象,它是String()构造函数的一个实例。就像这样,我们在JavaScript中表达了一个字符串值。注意我并不是建议使用构造函数,而不使用等价方式:字面量/原始值,如var string="foo";。但我建议,要理解字面量/原始值背后的内容。

如前所述,JavaScript语言具有以下原生预定义的构造函数:Number()、String()、Boolean()、Object()、Array()、Function()、Date()、RegExp()和Error()。可以在任意一个构造函数上应用new操作符来实例化一个对象实例。如下代码,构建了这9类原生JavaScript对象。Fiddle地址:http://jsfiddle.net/javascriptenlightenment/M9cWA/

通过使用new操作符,告诉JavaScript解释器,我们需要一个对应于构造函数实例的对象。例如,在上述代码中,Date()构造函数用于创建日期对象。Date()构造函数是日期对象的饼干模具。也就是说,它从Date()构造函数定义的默认模式中生成了日期对象。

至此,大家应该熟悉从原生构造函数[例如new String(‘foo’)]和用户自定义构造函数[例如new Person(true, 33, ‘male’)]创建对象实例的方法了。注意时刻记住,Math是一个静态对象——其他方法的容器,它不是使用new运算符的构造函数。1.6 从构造函数创建字面量值

JavaScript提供了叫做“字面量”的快捷方式——用于创建大多数原生对象值,而不必使用new Foo()或new Bar()这样的方式。大多数情况下,字面量语法与使用new操作符的效果相同。但是也有例外:Number()、String()和Boolean(),请看下面的注释。

如果你有其他编程背景,可能更熟悉用字面量方式创建对象。下面我使用new操作符实例化原生JavaScript构造函数,然后创建相应的字面量等价形式。Fiddle地址:http://jsfiddle.net/javascriptenlightenment/Nbkw4/

这里你需要注意的是,在一般情况下,使用字面量只是隐藏了与使用new操作符相同的基本过程。重要的是,它方便多了!

但在原始字符串、数字和布尔值方面,事情变得更复杂了。在这些情况下,字面量值具有原始值的特点,而不是复杂对象值的特点。请查看如下注意事项。注意在针对字符串、数字和布尔值使用字面量值时,只有在该值被视为对象的情况下才会创建实际的复杂对象。换句话说,在尝试使用与构造函数有关联的方法或检索属性(如var charactersInFoo = 'foo'.length)之前,一直在使用原始数据类型。当这种情况发生时,JavaScript会在幕后为字面量值创建一个包装器对象,以便将该值视为一个对象。调用方法以后,JavaScript即抛弃包装器对象,该值返回字面量类型。这就是字符串、数字和布尔被认为是原始(或简单)数据类型的原因。我希望这能够澄清对“JavaScript中的所有东西都是对象”与“JavaScript中所有东西都用成对象”这两个概念的误解。1.7 原始值(或简单值)

5、“foo”、true、false,以及null和undefined等JavaScript值都被视为原始值,因为它们是不可细化的。也就是说,数字是数字,字符是字符,布尔值则是true或false,null和undefined就是null和undefined。这些值本身是很简单的,不能表示由其他值组成的值。

查看下面的代码,并思考一下字符串、数字、布尔值、null和undefined值是否可以更加复杂。将它与你所知道的Object()实例或Array()实例或其他任何复杂对象进行比较。Fiddle地址:http://jsfiddle.net/javascriptenlightenment/xUQTC/

很简单,原始值是表示JavaScript中可用的数据/信息的最底层形式(即最简单的形式)。注意● 与使用字面量语法创建值相反,在使用new关键字创建String()、Number()或Boolean()值时,创建的对象实际上是一个复杂对象。● 了解String()、Number()和Boolean()构造函数是两种目的的构造函数,分别是用于创建字面量/原始值以及复杂值的,这是

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

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载