注意:

以下的输出都在浏览器的控制台中

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>闭包</title>
</head>
<body>
<script type="text/javascript">
/**
* 利用闭包实现
* 这个函数给对象o增加了属性存储器方法
* 方法名称为get<name>和set<name>。如果提供了一个判断函数
* setter方法就会用它来检测参数的合法性,然后再存储它
* 如果判定函数返回false,setter方法就会抛出一个异常
*
* 这个函数具有getter和setter函数
* 所操作的属性值并没有存储在对象o中
* 想反,这个值仅仅是保存在函数中的局部变量中
* getter和setter方法同样是局部函数,因此可以访问这个局部变量
* 也就是说,对两个存取器方法来设置或或修改这个值
*/
function addPrivateProperty(o,name,predicate) {
var value;//这是一个属性值 //getter方法简单地将其返回
o['get'+name] = function(){return value;}; //setter方法首先检查值示范合法,若不合法就会抛出异常
//否则就将其存储起来
o['set'+name] = function(v){
if(predicate && !predicate(v))
throw Error('set'+name+": invalid value "+v);
else
value = v;
};
} //想的代码展示addPrivateProperty()方法
var o = {};//设置一个空对象 //增加属性存储器方法getName()和setName()
//确保只语序字符串值
addPrivateProperty(o,"Name",function(x){return typeof x==="string";});
o.setName("Frank"); //设置属性值
console.log(o.getName()); //获取属性值
try{
o.setName(0); //设置一个非字符值,会抛出一个错误 (由throw语句抛出)
}catch(e){
console.log("属性值设置出错"); //上面抛出的错误在这里的到处理
} </script>
</body>
</html>
//第二部分代码:

//非共享闭包测试
function constfunc(v){
return function(){ //返回一个匿名数组
return v; //返回才外部变量 v,
};
} var funcs = [];
for(var i=0; i<10;i++)
funcs[i] = constfunc(i); for(i=0;i<funcs.length;i++)
console.log(funcs[i]()); //在funcs数组中保存的是匿名函数,可通过保存函数的变量后加"()"来执行匿名函数,
                   //获取匿名函数中的v的值
//输出:0 1 2 3 4 5 6 7 8 9 由于每次i的值被constfunc函数中的v所存储,注意是每次循环都是重新调用,因而能存到不同的内存空间 //共享闭包测试
function constfunc2(){
var funcs = [];
for(var i=0; i<10;i++)
funcs[i] = function(){ return i;};
return funcs;
}
var funcs = constfunc2(); console.log(funcs[0]());
console.log(funcs[3]());
console.log(funcs[7]());
console.log(funcs[9]());
//输出: 10 10 10 10
//原因:
//由于这个i在同一次函数调用中,同一个变量中(内存地址不变),
//所以当循环执行完i的值为10,在console.log()中的调用每次得到的都是同一个地址上的值,也就是10;
04-25 20:05