注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

梦幻雪冰

技在手,能在身,思在脑,从容过生活——陈能堡

 
 
 

日志

 
 

JavaScript 闭包  

2014-09-05 14:47:41|  分类: JavaScript |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

JavaScript 闭包-----梦幻雪冰

在了解闭包之前,先来回顾下JavaScript的作用域
【作用域一】

function show(){
blog = "梦幻雪冰";
console.log("函数内部变量:" + blog);
}show();
console.log("函数外部:" + blog);

【结果】
JavaScript 闭包 - 梦幻雪冰 - 梦幻雪冰
【结论】所有末定义直接赋值的变量,系统会自动声明为拥有全局作用域的变量,全局变量可以被函数内部访问。
【作用域二】

function show(){
console.log("函数内部变量:" + blog);
var blog = "梦幻雪冰";
}show();
console.log("函数外部:" + blog);

【结果】
JavaScript 闭包 - 梦幻雪冰 - 梦幻雪冰
【结论】函数内部可以访问函数外部的变量,但是反过来不行

闭包的定义:有权访问另外一个函数作用域的变量的函数,简单的认为闭包是来访问局部变量的函数。
常用闭包书写方式:一个函数内部创建另外一个函数
具体来看看简单的一个闭包  欢迎学习交流----
梦幻雪冰
【闭包一】

function creaname(){
var name = "独行冰海";
function sayname(){
console.log(name);
}
return sayname;
}
var fn = creaname();
fn();

【结果】输出的是 独行冰海
【结论】其实sayname就是闭包,闭包就是有权访问另外一个函数作用域的变量的函数;name变量是在creaname函数里面定义,所以name变量是属于局部变量,局部变量只能被creaname函数里面的函数访问(简单的说就是creaname里面的子级---sayname函数)。 欢迎学习交流----梦幻雪冰

进一步深入理解闭包
【闭包二】

function createFunction(){
var arr = new Array();
for (var i = 0; i < 10; i++) {
arr[i] = function(){
return i;
}
};
return arr;
}

var demoArr = createFunction();
for (var i = 0; i < demoArr.length; i++) {
console.log(demoArr[i]); //没有括号进行调用
};

【结果】
JavaScript 闭包 - 梦幻雪冰 - 梦幻雪冰
【结论】执行createFunction里面for循环的时候,把匿名函数存储到了数组里面。再者createFunction的返回值是数组,所以变量demoArr存放的就是数组(存储着匿名函数);

修改代码后

function createFunction(){
var arr = new Array();
for (var i = 0; i < 10; i++) {
arr[i] = function(){
return i;
}
};
return arr;
}

var demoArr = createFunction();
for (var i = 0; i < demoArr.length; i++) {
console.log(demoArr[i]()); //括号进行调用
};

【结果】
JavaScript 闭包 - 梦幻雪冰 - 梦幻雪冰10个10)
【结论】当执行createFunction();的时候,此时里面的i已经执行完了,i的值为10;匿名函数可以访问外部函数的所有变量,并且该变量不会被销毁。结合这两者可以发现它们都是引用同一个变量i(10个匿名函数都是共同访问一个变量i),所以才是弹出10个10;
画图来理解下:
JavaScript 闭包 - 梦幻雪冰 - 梦幻雪冰

为了让闭包的行为符合预期,修改代码如下   欢迎学习交流----梦幻雪冰
【闭包三】

function createFunction(){
var arr = new Array();
for (var i = 0; i < 10; i++) {
arr[i] = (function(num){
return function(){
return num;
};
})(i);

};
return arr;
}

var demoArr = createFunction();
for (var i = 0; i < demoArr.length; i++) {
console.log(demoArr[i]()); // 调用了
};

【结果】
JavaScript 闭包 - 梦幻雪冰 - 梦幻雪冰
【结论】此代码与上面的代码的一个区别就是匿名函数自我执行了(循环一次就调用一次),也就是说,当我执行var demoArr=createFunction();  这行代码的时候,createFunction内部的for循环的匿名函数立即返回直接的结果,因此createFunction函数返回的不再是匿名函数了,而是一个数组。所以 alert(demoarr[i]);直接打印即可,结果就是我们想要的。  

那么了解完了闭包之后,来看看闭包的this吧~
【闭包this一】

var user="独行冰海";
var obj={
user:"梦幻雪冰",
getUser:function(){
return function(){
return this.user;
};
}
};
console.log(obj.getUser()());

【结果】输出的是 独行冰海
【结论】匿名函数是属于window,那么this指向的是window,var user也是属于window,它的指向也是window。

修改代码后

var user="独行冰海";
var obj={
user:"梦幻雪冰",
getUser:function(){
var that = this;
return function(){
return that.user;
};
}
};
console.log(obj.getUser()());

【结果】输出的是 梦幻雪冰
【结论】我们可以看到,此时 return that.user;通过作用域链来到了var that=this这一行,而此时的this表示的就是obj对象(因为在getUser方法里),所以此时输出的就是梦幻雪冰。

闭包的缺点由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,所以不要过渡使用闭包,不然导致内存占用过多。建议只在绝对必要时候再考虑使用闭包。

欢迎学习交流----梦幻雪冰


欢迎学习交流——梦幻雪冰独行冰海@font-face中iefix的详解 - 梦幻雪冰 - 梦幻雪冰
HTML5学堂贴吧——HTML5学堂
HTML5学堂微博——HTML5学堂
  评论这张
 
阅读(214)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017