js 闭包理解
起因于周三的前端面试 面试官问我闭包的问题 我信誓旦旦的说 闭包是函数和它所包含的的外部环境 其实我是这样理解的 (哪里有问题希望指出 )
var a = 10;
function test() {
alert(a+1);
}
test();
这个只是一个函数的变量的作用域的问题 跟闭包貌似是无关了
所以我回来过了一天才开始想这个问题 下面是我的学习过程
首先我重新理解下了js中变量的作用域的问题
变量的作用域有全局变量和局部变量 js中函数内部能读取全局变量 而外部无法读取函数内部的局部变量
上面的例子就是函数内部读取全局变量的例子
而这样
function test() {
var n = 10;
}
alert(n);
会报错 n 未定义 //其实这是js中的作用域链的问题 当函数需要查询一个变量的值的时候 它先从本地的变量中找 找不到会不断的往上查找 所以 函数内部能读取全局的变量而函数外部不能读取内部的局部变量
我又了解了下js的垃圾回收机制 函数调用的时候先会为内部的变量分配内存供后面的代码操作 当函数执行完毕后这些分配了内存的变量就会被认为是没用的了 会被回收 但是会有这种情况 在函数中嵌套了另一个内部函数 这个函数可能会在外部调用并且它使用了外部函数的某些变量的话 当它被外部调用完后直接调用这个内部函数的话 这个内部函数可能无法读取它所需要的值(有可能被初始) 所以js解释器会自动将函数和它相关的变量包括父级变量打包 也就形成了闭包
上面这段话挺不好理解 可以这样理解就是函数和它包含的外部环境
写到这里我想举个我的例子 这次是去笔试 题目是这样的
<ul>
<li></li>
<li></li>
<li></li>
</ul>
第一个li alert 1 第2个alert2 所以我就这样写了
function test() {
var lis =
document.getElementsByTagName("li");
for(var i = 0;i < lis.length;
i++) {
lis[i].onclick = function() {
alert(i+1);
}
}
}
结果并不是我所想象的 差别很大。。。(全是alert4) 这里就有闭包的概念 function() {alert(i+1)} 与 外部的变量构成了闭包 但是为什么结果是这样呢? 是因为刚才我们只是获得外部变量的一个引用 所以得到的只是它最后的值
如何解决呢? 我们可以让内部函数在创建的时候立即执行 并且将外部变量的变量记录下来 在调用的时候使用并且返回
这样
function test() {
var lis =
document.getElementsByTagName("li");
var i = 0;
for(;i <
lis.length;i++) {
lis[i].onclick =
(function(j){
return function()
{
alert(j+1);
}
})(i);
}
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。