匿名函数
通常来说, 匿名函数 的使用情况是创建一个供以后使用的函数。有些情况下,函数并不需要名称引用。
如果不是真的需要函数名称,我们为什么要如此费心去创建一个独立的、带有名称的全局函数。JavaScript 的强大威力取决于是否作为函数式语言来使用,函数式编程专注于:少、通常无副作用和将函数作为程序代码的基础构件块。为了不让不必要的函数名称污染全局命名空间,我们将大量创建小型函数进行传递,而不是构建包含大量命令语句的大型函数。
递归
递归要满足两个条件:
- 引用自身。
- 有终止条件。
内联命名函数
尽管可以给内联函数命名,但是这些名称只能在自身函数内部才可见。内联函数的名称和变量名称类似,它们的作用域仅限于声明他们的函数。这也是为什么要将全局函数作为 window
的方法进行创建的原因,不使用 window
的属性,我们没有办法引用这些函数。
callee属性 (ES5中已经不推荐使用)
使用 arguments
参数的 calle
属性, 是另一种递归的方式的实现方式。callee
属性引用的是当前所执行的函数,该属性可以作为一个可靠的方法引用函数自身,所有这些不同的函数引用计数,在我们面临大规模复杂程序时提供了很大的帮助。从而避免了采用硬编码或脆弱的变量/属性名依赖。
注意:这一属性已经不再推荐使用,并且在"use strict"模式下会抛错
将函数视为对象
先给出一个简单的示例:
|
|
注意:适当放置分号,有助于压缩代码技术的发挥。
因为函数是第一型对象,所以也可以像如下这样:
|
|
和其他对象一样,函数也可以添加属性。它的这个特性可以有很多不同的使用方式,尤其是在事件回调管理方面。
函数存储
事件回调管理是最明显的例子,这里我们通过一个存储函数的例子来模拟给一个事件添加多个回调函数时,可能遇见的情形。
自记忆函数
通过暴露函数的属性,我们可以对函数自身进行修改。缓存记忆是构建函数的过程,这种函数通过记住先前的计算结果,从而避免执行已经算过的表达式。
以上的例子演示了函数的属性特性:可以将状态和缓存信息存储在一个封装的独立位置上。这样做,不仅在代码组织上有好处,更能在外部存储或缓存对象的作用域不受污染的情况下获得性能提升。
伪造数组方法
可变长度的参数列表
JavaScript 强大且灵活的特性之一是函数可以接受任意数量的参数,由于其没有重载,所以参数列表的灵活性是获得这一类似功能的关键。
使用 apply()
支持可变参数
函数重载
所有的函数都隐式的传递了 arguments
参数,这使得函数有能力处理任意数量的参数,不管我们定义了多少参数。
更好的函数重载方式,利用参数个数进行重载。根据期望的参数不同,每个函数也不同,而不是通过简单的 if-else
判断来实现重载,代码越复杂,效果越明显。
- 根据传入参数的类型执行不同的操作。
- 可以通过某些特定参数是否存在来进行判断。
- 通过传入参数个数来判断,即本例。
注意:不要将函数的 length
属性和 arguments
参数的 length
属性弄混淆,函数的 length
属性等于该函数声明时所需要传入的形参数量。
函数判断
如何判断一个给定的对象是一个函数的实例,并且可以调用,这其中会有跨浏览器的问题。
总结
- 匿名函数让我们能够创建更小的执行单元,而不是创建充满大量命令式语句的函数。
- 通过研究递归函数,我们学到了对函数进行引用的不同方式,包括:
- 通过名称引用。
- 作为一个方法进行引用(通过对象的属性名称)。
- 通过内联名称进行引用。
- 通过
arguments
的callee
属性进行引用。
- 函数可以拥有属性,并且这些属性可以用来保持任何我们想要的信息。
- 在函数属性中保持其它函数。
- 使用函数属性创建缓存。
- 通过函数上下文,我们可以在当前对象上执行该对象没有的方法。
- 基于所传递参数的不同,函数可以执行不同的操作。
- 函数判断,特别是跨浏览器的时候。