7,在 JavaScript 编程中,函数表达式是一种非常有用的技术。使用函数表达式可以无须对函数命名, 从而实现动态编程。匿名函数,也称为拉姆达函数,是一种使用 JavaScript 函数的强大方式。以下总结 了函数表达式的特点。
函数表达式不同于函数声明。函数声明要求有名字,但函数表达式不需要。没有名字的函数表
达式也叫做匿名函数。
在无法确定如何引用函数的情况下,递归函数就会变得比较复杂;
递归函数应该始终使用
arguments.callee
来递归地调用自身,不要使用函数名——函数名可
能会发生变化。
当在函数内部定义了其他函数时,就创建了闭包。闭包有权访问包含函数内部的所有变量,原理
如下。
在后台执行环境中,闭包的作用域链包含着它自己的作用域、包含函数的作用域和全局作用域。
通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。
但是,当函数返回了一个闭包时,这个函数的作用域将会一直在内存中保存到闭包不存在为止。
使用闭包可以在
JavaScript
中模仿块级作用域(
JavaScript
本身没有块级作用域的概念),要点如下。
创建并立即调用一个函数,这样既可以执行其中的代码,又不会在内存中留下对该函数的引用。
结果就是函数内部的所有变量都会被立即销毁——除非将某些变量赋值给了包含作用域(即外
部作用域)中的变量。
闭包还可以用于在对象中创建私有变量,相关概念和要点如下。
即使
JavaScript
中没有正式的私有对象属性的概念,但可以使用闭包来实现公有方法,而通过公
有方法可以访问在包含作用域中定义的变量。
有权访问私有变量的公有方法叫做特权方法。
可以使用构造函数模式、原型模式来实现自定义类型的特权方法,也可以使用模块模式、增强
的模块模式来实现单例的特权方法。
JavaScript
中的函数表达式和闭包都是极其有用的特性,利用它们可以实现很多功能。不过,因为
创建闭包必须维护额外的作用域,所以过度使用它们可能会占用大量内存。
8,浏览器对象模型(BOM)以 window 对象为依托,表示浏览器窗口以及页面可见区域。同时,window
对象还是
ECMAScript
中的
Global
对象,因而所有全局变量和函数都是它的属性,且所有原生的构造
函数及其他函数也都存在于它的命名空间下。本章讨论了下列
BOM
的组成部分。
在使用框架时,每个框架都有自己的
window
对象以及所有原生构造函数及其他函数的副本。
每个框架都保存在
frames
集合中,可以通过位置或通过名称来访问。
有一些窗口指针,可以用来引用其他框架,包括父框架。
top
对象始终指向最外围的框架,也就是整个浏览器窗口。
parent
对象表示包含当前框架的框架,而
self
对象则回指
window
。
使用
location
对象可以通过编程方式来访问浏览器的导航系统。设置相应的属性,可以逐段
或整体性地修改浏览器的
URL
。
调用
replace()
方法可以导航到一个新
URL
,同时该
URL
会替换浏览器历史记录中当前显示
的页面。
navigator
对象提供了与浏览器有关的信息。到底提供哪些信息,很大程度上取决于用户的浏
览器;不过,也有一些公共的属性(如
userAgent
)存在于所有浏览器中。
BOM
中还有两个对象:
screen
和
history
,但它们的功能有限。
screen
对象中保存着与客户端
显示器有关的信息,这些信息一般只用于站点分析。
history
对象为访问浏览器的历史记录开了一个
小缝隙,开发人员可以据此判断历史记录的数量,也可以在历史记录中向后或向前导航到任意页面。
9,客户端检测是 JavaScript 开发中最具争议的一个话题。由于浏览器间存在差别,通常需要根据不同 浏览器的能力分别编写不同的代码。有不少客户端检测方法,但下列是最经常使用的。
能力检测
:在编写代码之前先检测特定浏览器的能力。例如,脚本在调用某个函数之前,可能
要先检测该函数是否存在。这种检测方法将开发人员从考虑具体的浏览器类型和版本中解放出
来,让他们把注意力集中到相应的能力是否存在上。能力检测无法精确地检测特定的浏览器和
版本。
怪癖检测
:怪癖实际上是浏览器实现中存在的
bug
,例如早期的
WebKit
中就存在一个怪癖,即
它会在
for-in
循环中返回被隐藏的属性。怪癖检测通常涉及到运行一小段代码,然后确定浏
览器是否存在某个怪癖。由于怪癖检测与能力检测相比效率更低,因此应该只在某个怪癖会干
扰脚本运行的情况下使用。怪癖检测无法精确地检测特定的浏览器和版本。
用户代理检测
:通过检测用户代理字符串来识别浏览器。用户代理字符串中包含大量与浏览器
有关的信息,包括浏览器、平台、操作系统及浏览器版本。用户代理字符串有过一段相当长的
发展历史,在此期间,浏览器提供商试图通过在用户代理字符串中添加一些欺骗性信息,欺骗
网站相信自己的浏览器是另外一种浏览器。用户代理检测需要特殊的技巧,特别是要注意
Opera
会隐瞒其用户代理字符串的情况。即便如此,通过用户代理字符串仍然能够检测出浏览器所用
的呈现引擎以及所在的平台,包括移动设备和游戏系统。
在决定使用哪种客户端检测方法时,一般应优先考虑使用能力检测。怪癖检测是确定应该如何处理
代码的第二选择。而用户代理检测则是客户端检测的最后一种方案,因为这种方法对用户代理字符串具
有很强的依赖性。
10, DOM 是语言中立的 API,用于访问和操作 HTML 和 XML 文档。DOM1 级将 HTML 和 XML 文档
形象地看作一个层次化的节点树,可以使用
JavaScript
来操作这个节点树,进而改变底层文档的外观和
结构。
DOM
由各种节点构成,简要总结如下。
最基本的节点类型是
Node
,用于抽象地表示文档中一个独立的部分;所有其他类型都继承自
Node
。
Document
类型表示整个文档,是一组分层节点的根节点。在
JavaScript
中,
document
对象是
Document
的一个实例。使用
document
对象,有很多种方式可以查询和取得节点。
Element
节点表示文档中的所有
HTML
或
XML
元素,可以用来操作这些元素的内容和特性。
另外还有一些节点类型,分别表示文本内容、注释、文档类型、
CDATA
区域和文档片段。
访问
DOM
的操作在多数情况下都很直观,不过在处理
和
元素时还是存在一些
1
复杂性。由于这两个元素分别包含脚本和样式信息,因此浏览器通常会将它们与其他元素区别对待。这
些区别导致了在针对这些元素使用
innerHTML
时,以及在创建新元素时的一些问题。
理解
DOM
的关键,就是理解
DOM
对性能的影响。
DOM
操作往往是
JavaScript
程序中开销最大的
2
部分,而因访问
NodeList
导致的问题为最多。
NodeList
对象都是“动态的”,这就意味着每次访问
NodeList
对象,都会运行一次查询。有鉴于此,最好的办法就是尽量减少
DOM
操作。