1 <script language="javascript" type="text/javascript">
2   var a=1;
3   setTimeout('var a=2;alert(a)', 1000);
4   alert(a);
5   setTimeout('alert(a)',1000);
6 </script>//1 2 1;

setTimeout的异步我这里就不做过多的解释(异步回调,事件队列相关知识),主要写一下对一个参数是字串的时候注意的地方

从上面的代码中我们可以看出来,setTimeout的第一个参数为字串的时候,其实它相当于new 了一个Function在Function里面去定义的a变量,相当于:

1  <script language="javascript" type="text/javascript">
2      var a=1;
3      setTimeout(function(){var a=2;alert(a);}, 1000);
4      alert(a);
5      setTimeout(function(){alert(a);},1000);
6 </script>
7 //1 2 1;

1 <script language="javascript" type="text/javascript">
2     var a=1;
3     (new Function('var a=2;alert(a);')());
4     alert(a);
5     (new Function('alert(a);')());
6 </script>
7 //2 1 1

不知道为什么网上太多的人在说setTimeout/setInterval的时候都说污染全局变量,我感觉没污染全局变量啊,只是作用域的问题,就像下面的两个例子

另外我们在使用setTimeout的时候一般还是不要第一个参数传字串:

 1 function outer1(){
 2     function inner1(){
 3         setTimeout("inner2()",1000);
 4         setTimeout("outer2()",1000);
 5         alert("use inner1")
 6     }
 7     function inner2(){
 8         alert("use inner2")
 9     }
10     inner1();
11 }
12 outer1();
13 function outer2(){
14     alert("use outer2")
15 }
16 //use inner1,use outer2

 1 function outer1(){
 2     function inner1(){
 3         setTimeout(inner2(),1000);
 4         setTimeout(outer2(),1000);
 5         alert("use inner1")
 6     }
 7     function inner2(){
 8         alert("use inner2")
 9     }
10     inner1();
11 }
12 outer1();
13 function outer2(){
14     alert("use outer2")
15 }
16 //use inner1,use inner2,use outer2

对于第一个参数传字串来说,会在匿名函数中执行字串内容,这是就只能访问匿名函数体内定义的函数和变量或全局的变量和函数,所以出现了上面的结果。

再看一个例子:

 1 function A() {
 2     setTimeout("var a=2;alert(a)", 1000);
 3 }
 4 A();
 5 alert(a);//a is not define
 6 ==============================================
 7 function A() {
 8     setTimeout("var a=2;alert(a)", 1000);
 9     alert(a);//a is not define
10 }
11 A();
12 ============================================
13 function A() {
14     eval("var a=2;alert(a)", 1000);
15     alert(a);//2
16 }
17 A();
18 ============================================
19 function A() {eval("var a=2;alert(a)", 1000);}
20 A();
21 alert(a);//a is not define
22 ============================================
23 function A() {window.eval("var a=2;alert(a)", 1000);}
24 A();
25 alert(a);//2
26 ============================================
27 function A() {window.eval("var a=2;alert(a)", 1000);alert(a);//a is not define}
28 A();

但是对于eval函数来说就不是这样的了

1 <script language="javascript" type="text/javascript">
2     var a=1;
3     eval('var a=2;alert(a)');
4     alert(a);
5     setTimeout('alert(a)',1000);
6 </script>  //2 2 2;

eval函数会把里面的字串直接定义到当前作用域(当前执行的上下文)后面有提到window.eval和eval的区别是window.eval直接定义到作用域链的最顶端window下,不会向setTimeout和new Function那样会在一个闭包函数中去定义,所以eval函数不但会出现xss攻击的危险,还会存在变量污染的问题,所以我们要尽量减少多eval的使用,当有时候万不得已不需用到的时候,我们用new Function去代替eval也是可行的

当让这样也可以:

<script language="javascript" type="text/javascript"> var a=1;(function foo() {eval('var a=2;alert(a);');})();alert(a);setTimeout('alert(a)',1000);
</script>
//2 1 1;

最后还有一个需要注意的地方是:在版本号1.7以上的SpiderMonkey(内置于Firefox,Thunderbird)的实现中(这个是FF的ECMAScript解析引擎,相应的chrome V8,ie的JScript),可以把调用上下文作为第二个参数传递给eval。那么,如果这个上下文存在,就有可能影响“私有”(有人喜欢这样叫它)变量(这一段转自汤姆大叔blog)。

function foo() {  var x = 1;  return function () { alert(x); };};var bar = foo();bar(); // 1eval('x = 2', bar); // 传入上下文,影响了内部的var x 变量bar(); // 2

 最后一个非常值得注意的地方是eval既是ECMAScript的关键字有时window的一个属性,在运用的时候要注意以下的问题:
 1 function test(){
 2     eval('var a=10;')
 3     alert(a);//10
 4 }
 5 test();
 6 --------------------------------------------------------------------
 7 function test(){
 8     eval('var a=10;')
 9 }
10 test();
11 alert(a);//a is not defined
12 --------------------------------------------------------------------
13 function test(){
14     window.eval('var a=10;')
15 }
16 test();
17 alert(a);//10
18 --------------------------------------------------------------------
19 function test(){
20     var val=eval;
21     val('var a=10;')
22 }
23 test();
24 alert(a);//10

转载于:https://www.cnblogs.com/cdwp8/p/4059440.html

对setTimeout()第一个参数是字串的深入理解以及eval函数的理解相关推荐

  1. setTimeout 第一个参数类型

    读别人代码的时候看到这么一段,很不理解,然后就搜了一下百度 setTimeout / setInterval 第一个参数可以有三种类型: 字符串   .  methods  .  匿名函数 1.字符串 ...

  2. 查找一段文字中最长的重复字串 – 编程珠玑(排过序的后缀数组的应用)

    转自:https://www.cse.msu.edu/~liyang5/?p=53 <编程珠玑>在第15章"珍珠字符串"一节,给出了一个非常漂亮的实现 – 基于目标字符 ...

  3. @有两个含义:1,在参数里,以表明该变量为伪参数 ,在本例中下文里将用@name变量代入当前代码中2,在字串中,@的意思就是后面的字串以它原本的含义显示,如果不...

    @有两个含义:1,在参数里,以表明该变量为伪参数 ,在本例中下文里将用@name变量代入当前代码中 2,在字串中,@的意思就是后面的字串以它原本的含义显示,如果不加@那么需要用一些转义符\来显示一些特 ...

  4. linux sed第一列参数,linux sed笔记

    1.sed是干嘛的 它是一种在线编辑器.一次处理一行内容,主要用来自动编辑一个或多个文件:简化对文件的反复操作 处理过程:把当前处理的行存储在临时缓冲区中,一个称为"模式空间(pattern ...

  5. 信息学奥赛一本通 2050:【例5.20】字串包含 | OpenJudge NOI 1.17 19:字符串移位包含问题

    [题目链接] ybt 2050:[例5.20]字串包含 OpenJudge NOI 1.17 19:字符串移位包含问题 [题目考点] 1. 字符串 2. 判断一个字符串是不是另一个字符串的子串(字符串 ...

  6. 编程:使用递归方式判断某个字串是否回文(Palindrome)

    Answer: import java.util.Scanner; public class Palindrome { private static int len;//全局变量整型数据 privat ...

  7. 一步步教你优化Delphi字串查找(转载)

    一步步教你优化Delphi字串查找 2005-06-13 11:46 作者: 朱晓峰 出处: csdn开发高手 责任编辑:方舟 本人在编写离线浏览器WebSeizer的过程中,用到大量字符串处理函数, ...

  8. 【蓝桥杯】基础练习 01字串 对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。它们的前几个是:

    问题描述 对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能.它们的前几个是: 00000 00001 00010 00011 00100 请按从小到大的顺序输出这32种01串. 输入 ...

  9. java 字符串 字符查找_java之字符串中查找字串的常见方法

    1.int indexOf(String str) :返回第一次出现的指定子字符串在此字符串中的索引. int indexOf(String str, int startIndex):从指定的索引处开 ...

  10. python 分割字串_在Python中分割,连结和连结字串

    python 分割字串 There are few guarantees in life: death, taxes, and programmers needing to deal with str ...

最新文章

  1. 【渝粤教育】广东开放大学 21秋期末考试 公共政策学10855K1
  2. IDR、CRA、BLA、RASL、RADL、closed-gop、open-gop
  3. 【笔记】Linux的目录配置(a2)
  4. 谁说AI看不懂视频?
  5. 用 Java 开发自己的 Kubernetes 控制器,想试试吗?
  6. s2结业项目营业网点查询_论文发表完成科研项目的材料
  7. matlab2c使用c++实现matlab函数系列教程-wilkinson函数
  8. linux python安装pip_linux安装pip2.7
  9. 解决VB6.0中不能加载MSCOMCTL.OCX的错误提示
  10. win10笔记本电脑双系统 安装黑苹果系统macOS 小白黑苹果乐园下载资源简便安装黑苹果方式,非常详细,还有资源!
  11. 基于单片机的功放protues_音响放大器proteus仿真
  12. c语言把文件看作是一个字符序列,C语言对文件的操作
  13. MyBatis_1_MaBatis入门
  14. 路由器刷openwrt固件准备工作
  15. Git Error---bad signature 0x00000000 index file corrupt
  16. board crt_【大强哥-k8s从入门到放弃02】Kubernetes1.17部署Dashboard2.0
  17. JAVA项目经历的职责
  18. Flink process 和 apply 简单案例
  19. SecureCRT的安装及破解(详细过程)
  20. shell获取当前执行脚本的路径和文件名

热门文章

  1. 太极发送卡片软件_太极APP的入门级使用方法
  2. 单元测试的必要性 从bug修复 费用成本和时间成本综合考虑
  3. swift5的下标Subscripts 花式玩法
  4. 算法:还有比二分查找更快的算法,判断是否是子字符串Is Subsequence
  5. linux环境安装ffmepg,Linux centOS下安装FFmpeg
  6. IMPORTANT: You may need to close and restart your shell after running ‘conda init‘.
  7. java.io.FileWriter class doesn’t use UTF-8 by default
  8. 为什么xgboost/gbdt在调参时为什么树的深度很少就能达到很高的精度?
  9. 【Gym - 101234A】Hacker Cups and Balls【线段树 + 二分答案】
  10. 线性规划的标准型与规范型 (Standard and Canonical Forms)