异步作用域闭包
Posted llhweb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异步作用域闭包相关的知识,希望对你有一定的参考价值。
for(var i=0;i<=3;i++){ setTimeout(function() { console.log(i) }, 10);}
答案:打印4次4
这道题涉及了异步、作用域、闭包
settimeout是异步执行,10ms后往任务队列里面添加一个任务,只有主线上的全部执行完,才会执行任务队列里的任务,当主线执行完成后,i是4,所以此时再去执行任务队列里的任务时,i全部是4了。对于打印4次是:
因为for循环头部的let不仅将i绑定到for循环快中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。setTimeout里面的function()属于一个新的域,通过 var 定义的变量是无法传入到这个函数执行域中的,通过使用 let 来声明块变量,这时候变量就能作用于这个块,所以 function就能使用 i 这个变量了;这个匿名函数的参数作用域 和 for参数的作用域 不一样,是利用了这一点来完成的。这个匿名函数的作用域有点类似类的属性,是可以被内层方法使用的。
查了一下百度的一个答案:
setTimeout是一次执行函数,这里是10ms后执行,仅仅执行一次;for(var i=0;i<=3;i++),i的每次取值都是执行setTimeout这个函数,并没有执行setTimeout里面的function(即闭包函数),setTimeout里面的function是有setTimeout的定时触动的,也就是10ms后执行,也就是说i从0~3时,一共执行了4次的setTimeout()函数,此时的i的值是4,由于for语句的执行速度远小于1秒,所以,1秒后,由setTimeout()函数定时触动的闭包函数function()开始执行,alert(i);i的值已经是4了,所以相继打印4次i.
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> function btn1 () { // 通过var定义的变量,作用域是整个封闭函数,是全域的 。通过let定义的变量,作用域是在块级或是子块中。 // for (let i = 0; i < 5; i++) { // 0 1 2 3 4 // setTimeout(function() { // console.log(i) // }, 1000*i); // } for (let i = 0; i < 5; i++) { setTimeout(function() { // 5 5 5 5 5 console.log(i) }, 1000*i); } } function btn2 () { for (var i = 0; i < 5; i++) { // 0 1 2 3 4 (function(i) { setTimeout(function() { console.log(i); }, i * 1000); })(i); } } function btn3 () { for (var i = 0; i < 5; i++) { // 5 (function() { setTimeout(function() { console.log(i); }, i * 1000); })(i); } } function btn4 () { for (var i = 0; i < 5; i++) { // 0 1 2 3 4 setTimeout((function(i) { console.log(i); })(i), i * 1000); } } function btn5 () { setTimeout(function() { // 2 3 5 4 1 console.log(1) }, 0); new Promise(function executor(resolve) { console.log(2); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(3); }).then(function() { console.log(4); }); console.log(5); } </script> </head> <body> <button onclick="btn1()">setTimeout1</button> <button onclick="btn2()">setTimeout2</button> <button onclick="btn3()">setTimeout3</button> <button onclick="btn4()">setTimeout4</button> <button onclick="btn5()">setTimeout5</button> </body> </html>
以上是关于异步作用域闭包的主要内容,如果未能解决你的问题,请参考以下文章