javaScript中的匿名函数和闭包(第2篇)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>javaScript中的匿名函数和闭包(第2篇)</title>
<script type="text/javascript">
/*
作用域链的机制导致一个问题,在循环里的匿名函数取得的任何变量都是最后一个值
*/
//循环里的匿名函数的取值问题
function f1(){
var arr = [];
//循环里包含匿名函数
for (var index = 0; index < 5; index++) {
arr[index] = function (){ //arr[0]=0,arr[1]=1,arr[2]=2
return index;
};
}
//循环已经执行完毕了,index最终是index++等于5;那么最终就是5
return arr;
}
var result = f1();
// alert(result);
console.log(result);
console.log(result[0]);
console.log(result[1]);
console.log("===========数组长度" + result.length + "=============");
for (var i = 0; i < result.length; i++) {
console.log(result[i]);//结果全部都是匿名函数
console.log(result[i]()); //结果全部是5
console.log("*****************");
}
//改造版本1
function f2(){
var arr = [];
for (var index = 0; index < 5; index++) {
arr[index] = index;
}
return arr;
}
console.log("------------------------");
var result2 = f2();
for (var i = 0; i < result2.length; i++) {
console.log(result2[i]);
}
//改造版本2
function f3(){
var arr = [];
for (var index = 0; index < 5; index++) {
arr[index] = (function (num){ //通过自我即时执行匿名函数
return num;
})(index);
}
return arr;
}
console.log("------------------------");
var result3 = f3();
for (var i = 0; i < result3.length; i++) {
console.log('¥¥¥¥¥¥¥' + result3[i]);
}
//改造版本3
function f4(){
var arr = [];
for (var index = 0; index < 5; index++) {
arr[index] = (function (num){ //通过自我即时执行匿名函数
//num其实在这里
return function (){ //因为闭包可以将变量驻留在内存中,类似上次的闭包累加的案例,可以翻看上次闭包累加的案例
return num;
};})(index);
}
return arr;
}
console.log("------------------------");
var result4 = f4();
for (var i = 0; i < result4.length; i++) {
console.log(result4[i]);
console.log('$$$$$' + result4[i]());
}
//下面有个知识点
//这是立即执行函数,如下写法正确
(function() {
console.log('江西省赣州市于都县');
})();
//如下写法错误,如果立即执行函数没有赋值给一个变量的话,圆括号不可以省略(即必须加上圆括号)
// function() {
// console.log('中国江西省赣州市于都县');
// }();
//如下写法正确
var v1 = (function() {
console.log('江西省于都县');
})();
//如下写法正确,如果立即执行函数赋值给一个变量的话,圆括号可以省略
var v2 = function() {
console.log('赣州市于都县');
}();
//改造版本4
function f5(){
var arr = [];
for (var index = 0; index < 5; index++) {
arr[index] = function (num){ //通过自我即时执行匿名函数,这里我省略了圆括号
//num其实在这里
return function (){ //因为闭包可以将变量驻留在内存中,类似上次的闭包累加的案例,可以翻看上次闭包累加的案例
return num;
};}(index);
}
return arr;
}
console.log("------------------------");
var result5 = f5();
for (var i = 0; i < result5.length; i++) {
console.log(result5[i]);
console.log('%%%%%%%%' + result5[i]());
}
//在闭包中使用this关键字会导致的一些问题
//关于this对象
console.log(this); //this指的是Window
var vv = this;
console.log('!!!!!!!!!!!!!!' + vv + '-------------------');
//闭包在运行时,this指向Window
var v3 = {
getThis : function (){
return this;
}
};
console.log(v3.getThis()); //this指的是v3
var v4 = {
getThis : function() {
return function() {
return this;
}
}
};
console.log(v4.getThis()()); //this指的是Window
var address = '中国';
var message = {
address : '江西省赣州市于都县',
getAddress : function() {
return this.address;
}
};
console.log(address);
console.log(message.getAddress());
var address2 = 'China';
var message2 = {
address2 : 'China江西省赣州市于都县',
getAddress2 : function() {
return function() {
return this.address2;
};
}
};
console.log(address2);
//此时this指向Window
console.log(message2.getAddress2()()); //结果为China
//如何让闭包中的this不指向Window呢?有2种办法,对象冒充和作用域链
//1.对象冒充
//此时this指向message2
console.log(message2.getAddress2().call(message2));//结果为China江西省赣州市于都县
//2.作用域链
var address3 = 'I Love China';
var message3 = {
address3 : 'I Love China江西省赣州市于都县',
getAddress3 : function() {
var that = this; //此时that指向message3
return function() {
return that.address3;
};
}
};
//2.作用域链
//此时this指向message3
console.log(message3.getAddress3()());//结果为I Love China江西省赣州市于都县
</script>
</head>
<body>
<h1>javaScript中的匿名函数和闭包(第2篇)</h1>
<div id="div1" style="border: solid;height: 100px; background-color: #CDC5BF;">我是一个div层</div>
</body>
<script type="text/javascript">
//IE浏览器有内存泄露的问题,其他浏览器没有这个问题,看下面的案例
function fun6(){
var divNode = document.getElementById('div1'); //divNode用完之后,一直驻留在内存中
divNode.onclick = function (){
console.log(divNode.innerHTML); //这里用divNode导致内存泄露
};
}
fun6();
//改造版1
function fun7(){
var divNode = document.getElementById('div1');
divNode.onclick = function (){
console.log(divNode.innerHTML);
};
divNode = null; //解除引用,避免内存泄露
}
fun7(); //会报错divNode is null
//改造版2
function fun8(){
var divNode = document.getElementById('div1');
var text = divNode.innerHTML;
divNode.onclick = function (){
console.log(text);
};
divNode = null; //解除引用,等待垃圾回收
console.log('-------------' + divNode);
}
fun8();
</script>
</html>