首页 > 语言 > JavaScript > 正文

JavaScript闭包原理与用法实例分析

2024-05-06 15:31:52
字体:
来源:转载
供稿:网友

本文实例讲述了JavaScript闭包原理与用法。分享给大家供大家参考,具体如下:

1、与闭包有关的两个概念:

1) 变量的作用域

不带有关键字var的变量会成为全局变量;

在函数中使用关键字var声明的变量是局部变量。

局部变量只有在函数内部才能访问到,在函数外面是访问不到的。但在函数内部可以通过作用域链一直向上搜索直到全局对象,也就是说,函数内部可以访问函数外部的变量。

2) 变量的生存周期

对于全局变量,其生存周期是永久的,除非主动销毁这个全局变量;

而对于在函数内用关键字var声明的局部变量,当退出函数时,这些局部变量会随着函数调用结束而被销毁。

var func = function() {  var i = 1;  alert(i); // 输出:1};alert(i); // 报错:i is not defind.

例外情况:闭包

var func = function() {  var i = 1;  return function() {    alert(i);    i++;  }};var f1 = func();f1(); // 输出:1f1(); // 输出:2var f2 = func();f2(); // 输出:1f2(); // 输出:2

2、从闭包的一个经典应用谈起

<div>0</div><div>1</div><div>2</div><div>3</div><div>4</div><script>  var divs = document.getElementsByTagName("div");  for (var i = 0; i < divs.length; i++) {    divs[i].onclick = function() {      alert(i);    };  }</script>

问题:无论单击哪个div,都会弹出5。

原因:onclick事件是异步触发的,当事件被触发时,for循环早已结束,此时变量i的值早已经是5。

解决:在闭包的帮助下,把每次循环的i值都封闭起来。当事件函数顺着作用域链从内到外查找变量i时,会先找到被封闭在闭包环境的i,单击div时,会分别输出0,1,2,3,4。

<div>0</div><div>1</div><div>2</div><div>3</div><div>4</div><script>var divs = document.getElementsByTagName("div");for (var i = 0; i < divs.length; i++) {  divs[i].onclick = (function(num) {    return function() {      alert(num);    };  })(i);}</script>

类似实例:闭包直接赋给数组

function createFunctions() {  var result = new Array();  for (var i = 0; i < 10; i++){    result[i] = function(){      return i;    };  }  return result;}for (var i = 0; i < 10; i++)  alert(createFunctions()[i]());

结果:result的每个元素都返回10。

说明:闭包的作用域链有明显的副作用——闭包总是获得外部函数变量的最终值。上面代码中,外部函数产生一个函数数组result并返回。函数数组中的每个元素都是一个函数,每个函数都返回 i变量。似乎每个函数应该返回每次循环的i值,即依次返回0到9,但事实是,每个函数的返回结果都是10。这是因为每个内部函数返回的是变量i,而不是i在某个时刻的特定值,而i的作用域是整个外部函数,当外部函数执行完成后,i的值是10。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选