Solo  当前访客:0 开始使用

海西看月亮🌕

用心工作,用爱生活。

如何用JavaScript的for循环,原生和ES6写法|按秒依次输出指定数字

2019-08-20 07:27:03 yf98
0  评论    0  浏览

这个问题偶然在群里看见,就把大佬的回答记录下来了。

大佬写了两个一个是旧js的,一个是es6的。

这个是旧版JS的写法,为了构建一个隔离的作用域,防止setTimeout内部访问到全局的i变量,使用了iife函数,增加一个作用域(旧版JS只有函数可以独立作用域)。这样每次压入栈的setTimeout内部使用的i就是实时变化后的i,而不是最后的i。作用域从内层向上层寻找。

(function(){
 for (var i = 0; i < 3; i++) {
 	
 	(function(ii){
 		setTimeout(
 			function(){
 				console.log(ii);
 			},1000*ii);
 	})(i)
 }
})();

null


现在我们试试新的let:现在执行是依次输出 0 1 2 按照1s的顺序。

按照顺序入栈,由于函数提升,内部代码会被解析,但是未执行。

也就是说,内部i三次都会传入当前I的值,和上面的例子不同的是,let 声明的i是局部的,每次执行都是一个新的值!

上面的例子存在引用,当最后i变为3的时候,再去执行定时器内部的console引用的是全局变量i所以都是3,而现在这个例子,i不是全局的,当最后入栈的定时器执行时,i依旧是当时传入的i,第一次是0,第二次是1。

这里一定注意:两个例子都是传入了当时的i(0,1,2)。

但是最终执行的时候:

var 的i 是最终变化的为准(存在引用,传入1个旧的i)。

let 的i是每次传入新的i,不是引用先前的,所以,下面的例子输出是传入新的的i(传入3个新的i)。

如果下面代码给成 var 的,会输出3次3,因为函数提升后,最终执行的i是全局变量i,而i已经被改变了。


(function(){
 for (let i = 0; i < 3; i++) {
 		console.log("out:" + i);
 		setTimeout(
 			function(){
 				console.log(i);
 			},1000*i);	
 		
 }
})();

null

然后想起来setTimeout有第三个参数,就加上一个:其实目的就一个,让内层的参数与外层分离开。

这个写法也是旧版的,和第一个其实一样的,只是利用了函数的作用域。每次函数入栈,传入i,当开始执行时候,i就不是最外层了,因为内层有一个作用域。就近。

(function(){
 for (var i = 0; i < 3; i++) {
 		setTimeout(
 			function(ii){
 				console.log(ii);
 			},1000*i,i);	
 }
})();

null


标题:如何用JavaScript的for循环,原生和ES6写法|按秒依次输出指定数字
作者:yf_d
地址:看看我的CSDN

,



今日诗词
微信:13470849837

标签

友链

存档

TOP