定时器setTimeout/setInterval中变量报错:not defined 的解决方法

首先声明本人资质尚浅,如有错误,欢迎指正、共同提高。

-----------------------------------------------------------------------------------

首先声明:本文不重点讨论this作用域,而是讨论普通变量在定时器中容易报错的情况;

setTimeout的基本用法不再重述,

详见:http://www.w3school.com.cn/htmldom/met_win_settimeout.asp

bug:

  setTimeout的第一个参数有两种形式:

  1) 字符串code;  

  function test (){

    var a=1;

    setTimeout("a++",100);//a is not defined;

  }

  test();

  2) 函数形式;

  function test (){

    var a=1;

    setTimeout(function(){

      a++;

      console.log(a); //正常运行,却打印出结果2;

    },100);

  }

  test();

为什么第一种情况容易出错呢?

我们知道,setTimeout方法是挂在window对象下的。《JavaScript高级程序设计》第二版中,写到:“超时调用的代码都是在全局作用域中执行的,因此函数中this的值在非严格模式下指向window对象,在严格模式下是undefined”。在这里,我们只讨论非严格模式。

因而对于第一种形式(string code)的情况,定时器汇总调用的是全局变量a,而上下文中定义的变量是局部变量,所以会报错;

对于第二种形式(函数形式)可以这么理解:在这里匿名函数的使用形成了一个闭包,从而能访问到外层函数的局部变量。只是这种闭包,跟常见的闭包不同,因为函数式放在setTimeout里面。

-------------------------------------------------------------------------------

如有错误,欢迎评论指正、共同提高。[握手]

欢迎转载,转载请注明:转载自[ http://www.cnblogs.com/juneling ]

原文地址:https://www.cnblogs.com/juneling/p/8946107.html

时间: 2024-10-13 18:44:47

定时器setTimeout/setInterval中变量报错:not defined 的解决方法的相关文章

.NET下载文件报错System.UnauthorizedAccessException的解决方法

转自原文.NET下载文件报错System.UnauthorizedAccessException的解决方法 假设VS代码对应路径为E:\Projects\Web1,在VS用“发布Web”的方式发布后的路径为E:\Site\Web1.在IIS新建2个站点,站点A指向E:\Projects\Web1,站点B指向E:\Site\Web1. 现在出现一个异常情况,站点B能正常下载123.xls,站点A下载时却提示错误: System.UnauthorizedAccessException: 对路径“E:

git提交是报错没有change-id的解决方法

git提交是报错没有change-id的解决方法: 1.先仔细查看报错内容,查出是哪天提交记录缺少change-id 2.如果是最近的一条缺少,则直接执行git commit --amend "提交信息",以对上次提交的内容进行修改: 如果是前面几条都缺少change-id,则先 git reset --soft ****ddfd(恢复到最近一次有change-id的提交记录),重新提交$ git commit -am "提交信息" 重新提交修改记录 3.执行git

eclipse里index.jsp头部报错的原因和解决方法

index.jsp的头<%@这句报错的话,是因为没有引入Tomcat的原因. 解决: A:Window---Preferences---server---RuntimeEnviroments--Add--Apache中选择对应版本的汤姆猫---引入外部汤姆猫的安装目录 B:对着工程---右键---Build Path---Configure Build Path---Libraries---Add Library---    Server Runtime---选中汤姆猫即可!

MapReduce 程序运行报错 java.lang.ClassNotFoundException解决方法

在创建自定义的Mapper时候,编译正确,但上传到集群执行时出现错误: 11/16/05 22:53:16 INFO mapred.JobClient: Task Id : attempt_201111301626_0015_m_000000_0, Status : FAILED java.lang.RuntimeException: java.lang.ClassNotFoundException: actiondemo.MyJob$MapClass at org.apache.Hadoop.

mysql登陆启动报错 ERROR 2002 (HY000) 解决方法

报错信息 登陆数据库报错:` ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2 "No such file or directory")` 重启服务报错:Job for mariadb.service failed because the control process exited with error code. See &quo

oracle12c安装报错:PRVF-0002的解决方法

出错信息: 安装oracle12c, ./runInstaller 启动图形化报错 PRVF-0002 : Could not retrieve local nodename. 原因: 找不到主机名的对应ip 解决办法: 修改下/etc/hosts  添加 ip与主机名的映射即可

mybatis更新和插入语句报错的原因和解决方法

做一个小项目时,想实现添加和修改用户的功能,发现以下语句程序报错: INSERT INTO hrm_user(NAME,PASS_WORD,STATUS,DESC,role,createDATE,createUSER) VALUES('1','2','3','4','5','null','1') 改为以下语句即可通过: INSERT INTO hrm_user(`NAME`,`PASS_WORD`,`DESC`,`STATUS`,`createUSER`,`ROLE`) VALUES ('NAM

Mac下Notes报错NSSQLiteErrorDomain error 8解决方法

最近在Mac下Notes突然不能打开了,报如下错误: NSSQLiteErrorDomain error 8 这时,如果到System Preferences里,iCloud也打不开的,报错:Could not load iCloud preference pane. 打开Applications-->Utilities-->Console,看到如下类型的错误: 6/1/15 3:38:37.339 PM com.apple.NotesMigratorService[475]: SQLite:

canvas生成图片toDataURL报错的原因和解决方法

现象:在使用canvas的toDataURL()方法时,控制台有时会报错:Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. 原因:这是由于之前由drawImage()向canvas导入的图片跨域而导致的. 解决方法: 1.在引用图片之前打开跨域资源允许权限(一定要注意顺序): 1 var img=new Image;