前端开发javascript 闭包的掌握

前端的开发文档怎么写?|mac 前端免费开发工具|前端开发用到的技术
1.闭包的概念:是指有权访问另一个函数作用域中的变量的函数。#####2.创建闭包的常见方式:就是在一个函数内部创建另一个函数。#####3.注意:闭包只能取得包含函数中任何变量的最后一个值!闭包保存的是整个变量对象而不是特殊的某个变量。#####通过例子来理解:#####我们有三个链接,每点击一个链接要显示,点击的是第几条!#####最常见的错误写法如下:[code]<script>
var links = document.getElementsByTagName("a");
for(var i=0;i<links.length;i++ ){
        links[i].onclick = function(){
       alert("这是第"+(i+1)+"条!");
  };

}[/code]

很明显如果我们有3条,点击后出来的都是第4条!why?#####我是这么理解的,首先,我们直接把代码写在<script></script>中,相当于省略了window.onload = function(){………},所以links.onclick 相当于一个闭包(函数内部的函数)。其次,links.onclick = function(){…….}这是一个匿名函数,它与函数声明(function functionName(){………})区别在于:匿名函数是执行到它时再加载,而函数声明在执行前就加载! 所以links被点击后才会去执行匿名函数function(){alert(“这是第”)+(i+1)+”条”);}.#####那为什么i+1的值都是4呢? 因为i 是在外部函数中定义的 ,它先在内部函数中找i 并没有找到,于是去外部函数找,当onload执行完后i已经变成3了,在闭包中变量是不被释放的,会一直存在,所以i为3,当触发onclick后传入的i值是3 所以打出来i+1的值为4!!!#####正确的做法是什么呢?#####《javascript高级程序设计》中给过类似这样的例子,可以看一下:[code]<script>

var links = document.getElementsByTagName(“a”);
for( var i=0;i<links.length;i++ ){
links[i].onclick = function(num){
return function(){
alert(“这是第”+(num+1)+”条!”);
}
} (i);
}[/code]

##########我们来分析一下具体过程:#####首先,links.onclick 还是给了一个匿名函数 function(num){…….}但后面加上了(i),代表什么呢? 因为function(num){…}是个匿名函数 我们没法直接调用这个函数,所以我们直接在后面给她加上(参数)代表立马执行这个匿名函数,因此i就直接传给了num.#####其次,我们再看function(num){….}它的返回值返回的是一个函数,这个函数的返回结果是alert(“……”); 参数是已经传入值的num,所以这么执行时正确的#####原书中给的是这个例子:可以自行理解[code] function createFuncNew2(){
var func = new Array();
for( var i=0;i<10;i++){
func[i]=function(num){
return function(){
return num;//返回一个函数 这个函数的执行结果是num
}
}(i);
}
return func;
}
var func = createFuncNew2();
for( var i=0;i<func.length;i++){
document.write(func[i]()+”<br/>”);
}[/code]

ps: 网络上有大神给过别的正确实现方法,也很好,学习一下:
[code]<!DOCTYPE html PUBLIC “-//W3C//DTD html 4.0 Transitional//EN”>
<html>
<head>
<title></title>
<meta name=”” content=””>
</head>
<body>
<a href=”#”>第一条</a>
<a href=”#”>第二条</a>
<a href=”#”>第三条</a>
<script>
var links = document.getElementsByTagName(“a”);
for( var i=0;i < links.length; i++){
links[i].onclick = new showAlert(i);
}
function showAlert( num ){
return function(){
alert(“这是第”+(num+1)+”条!”);
};
}
</script>[/code]

这个写法也很好, 把onclick 对应的事件写在一个showAlert(num)对象里,初次onload时就已经传递参数生成对象了,所以打印结果也是正确的!
—————————————————————————————————————————————–2014/7/3 补充闭包可以用在许多地方。它的最大用处有两个,[color=#993300]一
个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中

怎么来理解这句话呢?请看下面的代码。

js代码
function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
alert(n);
}

    return f2;
  }
  var result=f1();
  result(); // 999
  nAdd();
  result(); // 1000
在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。
为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个
匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

小结: 之前写脚本时,特别依赖jquery,后来做在线测试发现,很多题要求你用原生javascript来写的!所以发现自己的javascript基础很弱啊!!!!延伸:如果要你一个事件绑定多个函数实现上述方法,且兼容浏览器,你怎么办?因此我们要学习attachEvent和addEventListener ![/color]

web前端开发技术介绍|前端开发怎么数据模拟|前端开发技术认识

» 本文来自:前端开发者 » 《前端开发javascript 闭包的掌握》
» 本文链接地址:https://www.rokub.com/4295.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!