We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在线答题网站
简单的来说,什么时候形成闭包呢?大多时候当一个内部函数被保存到外部时会形成闭包. 看一段简单的代码
function test(){ var arr = []; for(var i = 0;i<10;i++){ arr[i] = function(){ document.write(i + ""); } } return arr; var myarr = test(); for(var j = 0;j < 10;j++){ myarr[j](); }
乍一看这一段代码的结果可能是 0 1 2 3 4 5 6 7 8 9,然而并不是,这里就涉及了闭包。 正确的打印结果是10 10 10 10 10 10 10 10 10 10 大多数人会认为当内部for循环执行时就会立即将此时的i值赋给打印值,其实并不是。 test函数执行时,每次for循环都创建了一个函数保存在arr里面,但是函数内部是什么并不知道,此时
0 1 2 3 4 5 6 7 8 9
10 10 10 10 10 10 10 10 10 10
{ document.write(i + ""); }
这一段代码没有立即实行,他只是告诉arr[i]里保存了一个函数,相当于创建一个arr[i] = 函数这样一个东西。当·执行到return语句时。arr这个数组被保存到外部,也就是保存了十个相同的函数,每一个都有自己的执行期上下文和作用域链,但是此时的i已经变为了10,所以虽然函数执行十次,但每次打印出来的i都是同一个.他们的作用域里面保存着test的作用域,当然i值也就是用着同一个,典型的闭包。 那么要打印出不同值怎么办,来看下面的函数
arr[i] = 函数
function test(){ var arr = []; for(var i = 0;i<10;i++){ (function(j){ arr[j] = function(){ document.write(j + ""); } }(i)); } return arr; } var myarr = test(); for(var j = 0;j < 10;j++){ myarr[j](); }
这一次我们给他加了一层立即执行函数,当灭磁读取到function(j)时都会立即执行一次。i作为函数的实参,j为函数的形参,此时的函数直接相互独立,形成十个不同的函数·并不会受i值变化的影响,因此会打印出来0 1 2 3 4 5 6 7 8 9 下面再来看一个函数
function add(){ var num = 0; function a(){ console.log(++num); } return a; } var myadd = add(); myadd(); myadd(); myadd();
这一次函数打印出来的是1 2 3。这是一个很典型的闭包。 在add函数被执行时,他形成了一个自己的AO,a函数定义是他拿的是 add的AO以及GO,并且a函数被保存到了外部。 当add函数执行完毕后他的执行期上下文被销毁,这里就容易不懂,那么既然a的2执行期上下文被销毁,那么num应该不存在了,怎么会打印出num值。 其实在a函数被保存到外部时,就已经形成了一个闭包,他的作用域链里保存着add的执行期上下文,虽然add被销毁,但是a却被保存了,导致add的执行期上下文保存在a里面而无法被释放。此时的num值已经成为了a函数所有的,不存在于add里面,当然每次执行时num不会被初始化为0,所以num值会随着a函数的的执行而改变。 总的来说,闭包就是当内部函数被保存在外部时,导致原有的内部函数上级作用域链无法被释放,跟随着内部函数被保存到外部,此时的上级作用域链里的所有东西都归内部函数所有,相当于在内部函数里面定义的变量。当多个内部函数同时形成闭包时则用的是同一个作用域,里面的东西为函数公有,当你在一个函数里面改变某一变量的值,那么在另一函数里面调用这个变量时变量值已经是改变后的数值,
1 2 3
The text was updated successfully, but these errors were encountered:
js执行三部曲在下一期里介绍
Sorry, something went wrong.
No branches or pull requests
Qhappyman.github pages
每天解决一个问题发布
在线答题网站
19.2.27
理解闭包
简单的来说,什么时候形成闭包呢?大多时候当一个内部函数被保存到外部时会形成闭包.
看一段简单的代码
乍一看这一段代码的结果可能是
0 1 2 3 4 5 6 7 8 9
,然而并不是,这里就涉及了闭包。正确的打印结果是
10 10 10 10 10 10 10 10 10 10
大多数人会认为当内部for循环执行时就会立即将此时的i值赋给打印值,其实并不是。
test函数执行时,每次for循环都创建了一个函数保存在arr里面,但是函数内部是什么并不知道,此时
这一段代码没有立即实行,他只是告诉arr[i]里保存了一个函数,相当于创建一个
arr[i] = 函数
这样一个东西。当·执行到return语句时。arr这个数组被保存到外部,也就是保存了十个相同的函数,每一个都有自己的执行期上下文和作用域链,但是此时的i已经变为了10,所以虽然函数执行十次,但每次打印出来的i都是同一个.他们的作用域里面保存着test的作用域,当然i值也就是用着同一个,典型的闭包。那么要打印出不同值怎么办,来看下面的函数
这一次我们给他加了一层立即执行函数,当灭磁读取到function(j)时都会立即执行一次。i作为函数的实参,j为函数的形参,此时的函数直接相互独立,形成十个不同的函数·并不会受i值变化的影响,因此会打印出来
0 1 2 3 4 5 6 7 8 9
下面再来看一个函数
这一次函数打印出来的是
1 2 3
。这是一个很典型的闭包。在add函数被执行时,他形成了一个自己的AO,a函数定义是他拿的是 add的AO以及GO,并且a函数被保存到了外部。
当add函数执行完毕后他的执行期上下文被销毁,这里就容易不懂,那么既然a的2执行期上下文被销毁,那么num应该不存在了,怎么会打印出num值。
其实在a函数被保存到外部时,就已经形成了一个闭包,他的作用域链里保存着add的执行期上下文,虽然add被销毁,但是a却被保存了,导致add的执行期上下文保存在a里面而无法被释放。此时的num值已经成为了a函数所有的,不存在于add里面,当然每次执行时num不会被初始化为0,所以num值会随着a函数的的执行而改变。
总的来说,闭包就是当内部函数被保存在外部时,导致原有的内部函数上级作用域链无法被释放,跟随着内部函数被保存到外部,此时的上级作用域链里的所有东西都归内部函数所有,相当于在内部函数里面定义的变量。当多个内部函数同时形成闭包时则用的是同一个作用域,里面的东西为函数公有,当你在一个函数里面改变某一变量的值,那么在另一函数里面调用这个变量时变量值已经是改变后的数值,
闭包的坏处 :
内存泄露
其实很好理解,顾名思义,内存泄露则内存少了,闭包形成时原有作用域链没有被及时销毁,继续占用内存。就像手里握着一把沙子,沙子慢慢流出,也就是泄露,那么你手中的沙子会越来越少,内存泄漏就是这个道理。19.2.28
js执行三部曲
The text was updated successfully, but these errors were encountered: