闭包:有权访问另一个作用域中的变量的函数
- 执行环境(execution context)
- 作用域链(scope chain)
- 变量对象(variable object)
- 活动变量(activation object)
创建方式:在一个函数内部创建另一个函数。
活动对象:最开始为执行环境的argument对象,即作用域链最前端运行函数的[[Scope]]所包含的对象。
变量对象:执行环境中表示变量的对象。
作用域链:
- 用途:保证对执行环境有权访问的所有变量和函数的有序访问。
- 本质:为一个指向变量对象的指针列表,只引用而不包含变量对象。
闭包只能取得包含函数中任何变量的最后一个值。
function(){
var result = new Array();
// 数组中每个对象都指向同一个变量i;
// i只保存最后一个值;
for (var i = 0; i<10; i++){
result[i] = function(){
return i ;
};
};
// 所有返回变量i的值为10;
return result;
}
通过增加一个闭包函数达到每个函数都获得不同的索引值
function createFunctions(){
var result = new Array();
for (var i=0; i<10; i++){
// 匿名函数
//将执行过的匿名函数结果,赋值给数组
result[i] = function(num){
//闭包
return function(){
return num;
}
}(i)
}
return result;
}
- result[i] 取不到闭包函数中变量 num ,每个函数得到的是匿名函数的执行结果。
- num已经形成内部私有变量,外部一旦调用num,num值不会被销毁。
- 匿名函数的参数是由变量i的当前值复制给参数num而获得,所以result数组中每个函数内部都有属于自己的num变量的副本。
块级作用域(私有作用域)
用于自定义类型创建私有变量和特权方法。
- 语法
(function(){
//这里是块级作用域
})();
括号1中包含一个函数声明,将函数声明转化为函数表达式(函数表达式可调用,函数声明只是声明);
括号2表示立即调用这个函数。
私有变量
特权方法:可访问私有变量和私有函数的公有方法。
创建方式:
在构造函数中定义特权方法;(构造函数相同,每次方法都会重建。)
通过在私有作用域中定义私有变量或函数(静态私有变量)。
1.创建一个私有作用域;
function MyObject(){
// 私有变量和私有函数
var privateVariable = 10;
function privateFunction(){
return false;
}
//特权方法
this.publicMethod = function(){
privateVariable++;
return privateFunction();
};
}
2.在其中封装一个构造函数及公有方法(构造函数是使用函数表达式定义的全局变量);
3.公有方法是在原型上定义的。
(function (){
var privateVariable = 10;
function privateFunction(){
return false;
};
//构造函数
MyObject = function(){
};
//公有/特权方法
MyObject.prototype.publicMethod = function(){
privateVariable++;
return privateFunction();
}
})();
模块模式(module pattern)
为单例创建私有变量和特权方法
- 单例
- 定义:只有一个实例的对象;
- 创建:对象字面量方式。
var singleton = {
name : value,
method : function(){
// 这里是方法的代码
}
}
模块模式通过为单例添加私变量和特权方法使其得到增强, 语法:
var singleton = function{
// 私有变量和私有函数
var privateVarible = 10;
function privateFunction(){
return false;
}
// 特权/公有方法和属性
// 对象字面量
//公共方法,外部接口
return{
publicProperty: true,
//公有方法可访问私有变量和函数
publicMethod: function(){
privateVarible ++;
return privateFunction();
}
};
}();
将对象字面量作为函数的值返回,返回的值中有公开的方法和属性,即为单例的公共接口,可用于维护函数的私有变量和初始化某些变量。
增强的模块模式
适合于单例必须是某种类型的实例。
var single = function(){
// 私有变量和私有函数
var privateVarible = 10;
function privateFunction(){
return false;
};
// 公共方法,外部接口,规定返回的类型
var object = new CustomType();
object.publicProperty = true;
object.publicMethod = function(){
privateVarible++;
return privateFunction();
}
return object;
}()
演示application对象必须是BaseComponent的实例,那么可以使用以下代码。
var application = function(){
//私有变量和函数
var components = new Array();
//初始化
components.push(new BaseComponent());
//创建application的一个局部副本
var app = new BaseComponent();
//公共接口
app.getComponentCount = function(){
if (typeof component == "object"){
components.push(component);
}
}
//返回这个副本
return app;
}();
模块模式与增强模块模式的区别在于变量app的创建过程,因其必须是某种类型的实例,所以通过new来创建。