要想理解closure,最好是写一些代码,或是看一些例子。Closure提供了封装(encapsulation)
function myClosure(){
var date = new Date();
//nested function
return function(){
return date.getMilliseconds();
}
}
即使是当myClosure中的匿名函数(closure)返回,但是date变量仍然驻留在内存中,而不想普通的函数执行完成后就被garbage collection回收了。这里把myClosure看作是一个容器,而date和nested function被看做是这个容器中的元素。
另外一种实现方式:
var myClosure2 = function(){
var date = new Date();
var myNestedFunc = function(){
return date.getMilliseconds();
}
return {// revealing modular pattern
foo: myNestedFunc
}
}
var bar = new myClosure2();
console.log(bar.foo());
定义变量?
标准方式定义变量
var str = “Hello World”;
如果定义多个变量的话,可以采用:
var str1 = ‘hello’,
str2 = ‘world’,
str3 = ‘foo bar’;
改写上面的:
var myClosure2 = function(){
var date = new Date();
var myNestedFunc = function(){
return date.getMilliseconds();
}//这里JSLint会给出警告,并且显得var定义使用了多次
return {// revealing modular pattern
foo: myNestedFunc
}
}
改写:
var myClosure2 = function(){
var date = new Date(),
var1 = 5,
myNestedFunc = function(){
return date.getMilliseconds();
};
return {// revealing modular pattern
foo: myNestedFunc
}
}
Prototype Pattern
优点:
<!--[if !supportLists]-->l <!--[endif]-->充分利用JavaScript内建特性
<!--[if !supportLists]-->l <!--[endif]-->“Modularize”代码为了构建可重用代码
<!--[if !supportLists]-->l <!--[endif]-->让变量和函数脱离全局作用域
<!--[if !supportLists]-->l <!--[endif]-->函数在内存中只加载一次
<!--[if !supportLists]-->l <!--[endif]-->通过prototype可能override函数
缺点:
<!--[if !supportLists]-->l <!--[endif]-->this指针很容易混淆
<!--[if !supportLists]-->l <!--[endif]-->Constructor脱离prototype定义
Prototype pattern结构
var Calculator = function(eq){//定义一个对象
this.eqCtl = document.getElementById(eq);
}
Calculator.prototype = {//扩展对象原型链上的方法
add: function(x, y){//封装,不污染全局作用域
var val = x + y;
this.eqCtl.innerHTML = val;
}
}
var calc = new Calculator(‘eqCtl’);
calc.add(2,2);
Prototype Pattern一般用在实现一个类的功能,这个类中有一些属性和操作,这些操作要访问这些属性的值,定义函数对象(可以理解为类的模板)时就是初始化属性值,然后通过原型链来定义操作,这些操作是针对所有后期被实例化的对象,这些操作只被内存加载一次,但是个个实例化对象的属性都是独占内存的。
<!--EndFragment-->