《Javascript高级程序设计》第七章——函数表达式学习笔记

来源:互联网 发布:do not tag 淘宝网 编辑:程序博客网 时间:2024/05/17 01:47

函数声明可以在调用语句之后,函数表达式必须先赋值再调用。

一、递归

arguments.callee: 指向正在执行的函数的指针。求阶乘的函数可以如下实现:



二、闭包

1、闭包作用域链

作用域链本质上是指向变量对象的指针列表。全局环境的变量对象始终存在。

如果在全局作用域中创建了一个函数,那么也会为这个函数创建一个包含全局变量对象的作用域链。被保存在函数的scope属性中。当调用此函数时,会为函数创建一个执行环境,然后通过复制函数的scope属性构建起执行环境的作用域链。此后,又有一个活动对象(在此作为变量对象使用),被创建并被推入执行环境作用域链的顶端。

在另一个函数内部定义的函数,初始化时会将包含它的函数(外部函数)的活动对象添加到他们作用域中。外部函数执行完毕后,活动对象不会被销毁,因为匿名函数或者说闭包的作用域仍然在引用这个活动对象。所以对于外部函数,仅仅是销毁了它的作用域链。直到闭包被销毁,外部函数的活动对象才会被销毁。


上面这段代码,result是一个函数数组,每个result[i]指向一个函数副本。但是所有的匿名函数function() 指向的是同一个i(外部函数的变量)。所以调用每一个result[i]返回相同值。


上面这段代码,result同样是一个函数数组,每个result[i]指向一个函数副本。但是因为函数参数是按值传递,所以每个匿名函数都会得到当前的i值。

 2、this对象

this对象指向的是包含它的最内层函数的调用者。this对象是在运行时基于函数的执行环境动态绑定的。函数在全局被调用时,this等于window对象;函数作为某对象的成员方法被调用时,this等于那个对象。

每个函数在被调用时,其活动对象都会自动取得两个特殊变量,this和arguments。内部函数在搜索这两个变量时,只会搜索到它们自己的活动对象中的this,因而不可能访问到外部函数的this。但是如果把外部作用域中的this保存为另一个变量,由于内部函数不具备这个变量,因为访问时就会搜索到外部函数的活动对象,所以可以让闭包访问该对象了。如下所示:



在闭包使用中记得避免内存泄露,使用null赋值的方法减少对dom元素的引用。

三、模仿块级作用域

私有作用域(或者叫做块级作用域)的语法如下:

(function() {

})();

这段代码定义的了一个匿名函数并立刻调用了它。function() {}外又加一层括号是为了使它变成函数表达式,如果不加的话就只是函数声明。函数声明后面不可以跟圆括号,函数表达式可以。

这种技术经常在全局作用域中被用在函数外面,以免向全局作用域中添加过多的变量。

四、私有变量

函数的参数、局部变量、内部定义的函数都算作私有变量。私有变量是不能在函数外被访问的。但是我们可以利用闭包创建可以访问私有变量的公有方法。这种方法被称为特权方法。

没用使用var关键字定义的变量都是全局变量。

1、静态私有变量

在私有作用域中定义公有方法。


如上图代码,变量name成为所有实例共享的静态私有变量。


2、模块模式

模块模式是为单例创建私有变量和特权方法。单例是指只有一个实例的对象,javascript以对象字面量的方式创建单例对象。如下。


使用方式如下:


这种方式用于需要对单例进行某些初始化并且维护其私有变量时使用的(不太了解其应用场景)。




0 0
原创粉丝点击