什么是闭包
闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包的特点:
1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
简单的说,Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
JS中一切都是对象,函数是对象的一种。
闭包的写法:
第一种写法----采用的是给函数添加一些属性:
function Circle(r) {
this.r = r;
}
Circle.PI = 3.14159;
Circle.prototype.area = function() {
return Circle.PI * this.r * this.r;
}
var c = new Circle(2.0);
console.log( c.area() );
第二种写法----将一个函数当作值赋给变量:
//第2种写法
var Circle = function() {
var obj = new Object();
obj.PI = 3.14159;
obj.area = function( r ) {
return this.PI * r * r;
}
return obj;
}
var c = new Circle();
console.log( c.area( 2.0 ) );
第三种----new 一个对象,然后给对象添加属性和方法
var Circle = new Object();
Circle.PI = 3.14159;
Circle.Area = function( r ) {
return this.PI * r * r;
} console.log( Circle.Area( 1.0 ) );
第四种----直接定义变量,用的比较多
var Circle={
"PI":3.14159,
"area":function(r){
return this.PI * r * r;
}
}; console.log( Circle.area( 1.0 ) );
闭包的用途:
1、匿名自执行函数
除了每次使用变量都是用var关键字外,我们在实际情况下经常遇到这样一种情况,即有的函数只需要执行一次,其内部变量无需维护,比如UI的初始化,那么我们可以使用闭包:
2、结果缓存
我们开发中会碰到很多情况,设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,
那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
var CachedSearchBox = (function(){
var cache = {},
count = [];
return {
attachSearchBox : function(dsid){
if(dsid in cache){//如果结果在缓存中
return cache[dsid];//直接返回缓存中的对象
}
var fsb = new uikit.webctrl.SearchBox(dsid);//新建
cache[dsid] = fsb;//更新缓存
if(count.length > 100){//保正缓存的大小<=100
delete cache[count.shift()];
}
return fsb;
},
clearSearchBox : function(dsid){
if(dsid in cache){
cache[dsid].clearSelection();
}
}
};
})();
CachedSearchBox.attachSearchBox("input");
3、封装
var person = function(){
//变量作用域为函数内部,外部无法访问
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
print(person.name);//直接访问,结果为undefined
print(person.getName());
person.setName("abruzzi");
print(person.getName());
得到结果如下:
undefined
default
abruzzi
4、实现类和继承
function Person(){
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
};
var p = new Person();
p.setName("Tom");
console.log(p.getName());
var Jack = function(){};
//继承自Person
Jack.prototype = new Person();
//添加私有方法
Jack.prototype.Say = function(){
console.log("Hello,my name is Jack");
};
var j = new Jack();
j.setName("Jack");
j.Say();
console.log(j.getName());
定义了Person,它就像一个类,我们new一个Person对象,访问它的方法。
下面我们定义了Jack,继承Person,并添加自己的方法。
运行结果:Tom
Hello,my name is Jack
Jack
[Finished in 0.5s]