版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/twilight_karl/article/details/60592592
闭包
1,闭包可以让局部变量驻留在内存中,而不会重复初始化
2,过度使用会导致内存占用过高,因此用完后应及时解除引用:
b = null
function add(){
var num = 100;
return function(){
return num++;
};
};
var fun3 = add(); // 获得闭包函数,add函数只初始化一次
alert(fun3()); // 101
alert(fun3()); // 102
alert(fun3()); // 103
alert(fun3()); // 104
fun3 = null; // 过多的使用闭包会占用大量内存,使用完后要释放闭包函数:
alert(fun3()); // 报错
以循环里的匿名函数的取值为例,分三种情况:
<1>: 返回的闭包函数由于是在sum执行完后再执行,所以返回的值都是5.数组中保存的是匿名函数,需要用函数的方式调用。
// 001
function sum(){
var arr = new Array();
for(var i=0;i<5;i++){
arr[i] = function(){
return i;
}
};
return arr;
};
var data = sum();
for( var i=0;i<5;i++){ // 全部是5
alert(data[i]());
}
<2>: 利用函数的自我执行即时的给数组赋值,返回的数组内容是数字
// 002
function sum(){
var arr = new Array();
for(var i=0;i<5;i++){
arr[i] = (function(num){ // 匿名函数的即时执行
return num;
})(i);
};
return arr;
};
var data = sum();
for( var i=0;i<5;i++){ // 正常
alert(data[i]);
}
<3>: 使用函数的自我执行的同时返回一个匿名函数,返回的数组需要当成函数调用
// 003
function sum(){
var arr = new Array();
for(var i=0;i<5;i++){
arr[i] = function(num){ // 匿名函数的即时执行
return function(){
return num;
};
}(i);
};
return arr;
};
var data = sum();
for( var i=0;i<5;i++){ // 正常
alert(data[i]());
}
闭包中的this
闭包中的this指向window,闭包并不属于某个对象的属性和方法。解决方法:对象冒充。
var flag = "window";
var box = {
flag : "box",
fun : function(){
return function(){
return this.flag;
}
}
};
alert(box.fun()()); // 闭包的this指向window
可以使用以下的方法解决,不直接使用闭包中的this,而是保存普通函数中的this,再在闭包中调用:
var box2 = {
flag : "box",
fun : function(){
var sss = this;
return function(){
return sss.flag;
}
}
};
alert(box2.fun()()); // box2
使用call或者apply更改作用域也可以解决问题:
var box3 = {
flag : "box",
fun : function(){
return function(){
return this.flag;
}
}
};
alert(box3.fun().call(box3));
私有作用域
JavaScript没有块级作用域,但是自我执行的匿名函数有私有作用域,作用域中的变量在执行完后就被销毁,在作用域外无法被调用。可以减少全局变量的使用。
(function(){
for(var i=0;i<5;i++){}
})();
alert(i); // undefined
私有变量
this.属性或this.方法表示的是共有方法和属性。但是在方法中用var声明的方法或属性是私有属性,外部无法调用,用该函数创建的对象也无法使用私有属性。
function Person(str){
var name = str; // 私有属性
var fun = function(){ // 私有方法
return name+"###";
};
};
var tom = new Person("Tom");
alert(tom.fun()); // 报错
alert(tom.name); // 报错