JavaScript setTimeout使用闭包功能实现定时打印数值


Posted in Javascript onDecember 18, 2015

我们这次使用setTimeout来实现一个按照时间定时,依次打印数值的例子.其实在早期的时候,也是我经常犯的一个错误,或者实现这种能力,似乎js比较牵强,其实是我的错,哈哈!没能理解JS强大之处.我们直接进入主题吧!   注意,如果用setInterval来实现的话,那肯定很简单,这次我们是使用setTimeout.   我们先从最简单思考入手.那就会写出下面的代码.

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

这段代码虽然依次打印了,每个i的值0,1,2,3,4.但是,执行的时间却没有起作用.为什么呢? 因为 console.log() 是方法的执行调用,在调用这个方法后,当是马上执行!,所以没有达到我们预期的目的。  

那我们继续看下面一段代码

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

这里我们使用一个匿名函数包含了打印的console.log来打印i,所以 i这个值是共享的,还没等到执行第一个setTimeout的时候,for循环已经执行完成,最后的i = 5,所以i 会打印四次   其实我们两种解决办法,我们先来看第一种:

var j = 0; function abc(){ console.log("j = "+j); j++; }  
for(var i = 0; i < 10; i++ ){ 
setTimeout(abc,i*1000) }

这里我们另外一个全局变量来存储值,每执行一次函数abc,j就加一次,所以执行到setTimeout的时候,就会调用abc函数,所以会达到我们预期的效果,但是这里这个j是一个全局变量,全局变量会造成容易改变其值或者命名冲突等问题.   第二种办法的实现,我们再次引入闭包函数.因为闭包函数,每一次创建都会存在一个自己的空间来存储唯一的值.所以利用这个思维.我们把代码写成下面的代码.

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

我们将i的每一次执行for循环的值,传给不同创建的闭包函数,这样每一个闭包函数里存储的i值,就都不会一样.所以就是达到我们的想要的结果.

ps:使用闭包对setTimeout进行简单封装

在写js脚本时,经常会用到一些拼写函数的情况,例如调用setTimeout

var msgalert="test"; 
 function TestAlert(msg) 
   { 
    alert(msg) 
   } 
    
   $(document).ready(function () { 
  $("#btnCancel").click(function (e) { 
    setTimeout("TestAlert("+msgalert+")",1000); 
    }); 
})

查了很长时间,为什么就是弹不出对话框呢。检查了很长时间才发现,原来是少了一对单引号

$(document).ready(function () { 
  $("#btnCancel").click(function (e) { 
    setTimeout("TestAlert('"+msgalert+"')",1000); 
    }); 
})

这样的写法容易出错,还不容易检查出错误,如果使用闭包就可完全避免,改写如下

var msgalert="test"; 
  function dalayAlert(msg ,time){  
  setTimeout( 
  TestAlert(msg), 
  time 
  ); 
  }  
 function TestAlert(msg) 
 { 
  alert(msg) 
 } 
$(document).ready(function () {   
$("#btnCancel").click(function (e) { 
   dalayAlert(msgalert,1000) 
 });

由于使用了闭包,也简单了很多,检查错误也很容易了

Javascript 相关文章推荐
js确定对象类型方法
Mar 30 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
Nov 22 Javascript
JQuery与Ajax调用新浪API获取短网址的代码
Feb 07 Javascript
escape函数解决js中ajax传递中文出现乱码问题
Oct 30 Javascript
jquery简单倒计时实现方法
Dec 18 Javascript
点评js异步加载的4种方式
Dec 22 Javascript
JavaScript事件处理的方式(三种)
Apr 26 Javascript
JS作用域深度解析
Dec 29 Javascript
JS简单封装的图片无缝滚动效果示例【测试可用】
Mar 22 Javascript
jquery.onoff实现简单的开关按钮功能(推荐)
May 24 jQuery
bootstrapTable+ajax加载数据 refresh更新数据
Aug 31 Javascript
vue组件通信传值操作示例
Jan 08 Javascript
jquery获取css的color值返回RGB的方法
Dec 18 #Javascript
jQuery实现textarea自动增长宽高的方法
Dec 18 #Javascript
jquery简单倒计时实现方法
Dec 18 #Javascript
js命名空间写法示例
Dec 18 #Javascript
JavaScript Split()方法
Dec 18 #Javascript
jquery中object对象循环遍历的方法
Dec 18 #Javascript
JavaScript的Number对象的toString()方法
Dec 18 #Javascript
You might like
VFP与其他应用程序的集成
2006/10/09 PHP
PHP5函数小全(分享)
2013/06/06 PHP
php使用MySQL保存session会话的方法
2015/06/18 PHP
php中各种定义变量的方法小结
2017/10/18 PHP
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
2010/11/20 Javascript
javascript数字格式化通用类 accounting.js使用
2012/08/24 Javascript
jquery使用ajax实现微信自动回复插件
2014/04/28 Javascript
thinkphp实现无限分类(使用递归)
2015/12/19 Javascript
JS函数的定义与调用方法推荐
2016/05/12 Javascript
微信小程序 开发指南详解
2016/09/27 Javascript
浅谈jquery页面初始化的4种方式
2016/11/27 Javascript
js仿京东轮播效果 选项卡套选项卡使用
2017/01/12 Javascript
微信小程序 引入es6 promise
2017/04/12 Javascript
Vue学习笔记进阶篇之vue-cli安装及介绍
2017/07/18 Javascript
基于Bootstrap的标签页组件及bootstrap-tab使用说明
2017/07/25 Javascript
Promise.all中对于reject的处理方法
2018/08/01 Javascript
vue项目设置scrollTop不起作用(总结)
2018/12/21 Javascript
React 实现拖拽功能的示例代码
2019/01/06 Javascript
使用pm2自动化部署node项目的方法步骤
2019/01/28 Javascript
vue路由--网站导航功能详解
2019/03/29 Javascript
Vue插件之滑动验证码
2019/09/21 Javascript
Javascript中Math.max和Math.max.apply的区别和用法详解
2020/08/24 Javascript
[49:35]2018DOTA2亚洲邀请赛3月30日 小组赛A组 KG VS TNC
2018/03/31 DOTA
python实现批量图片格式转换
2020/06/16 Python
Python一行代码解决矩阵旋转的问题
2019/11/30 Python
keras获得model中某一层的某一个Tensor的输出维度教程
2020/01/24 Python
python报错TypeError: ‘NoneType‘ object is not subscriptable的解决方法
2020/11/05 Python
web字体加载方案优化小结
2019/11/29 HTML / CSS
台湾线上百货零售购物平台:friDay购物
2017/08/18 全球购物
设计专业自荐信
2014/06/19 职场文书
2014年纪检监察工作总结
2014/11/11 职场文书
2014年综合治理工作总结
2014/11/20 职场文书
毕业论文致谢范文
2015/05/14 职场文书
在python中实现导入一个需要传参的模块
2021/05/12 Python
Vue和Flask通信的实现
2021/05/19 Vue.js
SpringBoot集成Redis的思路详解
2021/10/16 Redis