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

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

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

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

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

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

 function outer1(){
function inner1(){
setTimeout("inner2()",1000);
setTimeout("outer2()",1000);
alert("use inner1")
}
function inner2(){
alert("use inner2")
}
inner1();
}
outer1();
function outer2(){
alert("use outer2")
}
//use inner1,use outer2
 function outer1(){
function inner1(){
setTimeout(inner2(),1000);
setTimeout(outer2(),1000);
alert("use inner1")
}
function inner2(){
alert("use inner2")
}
inner1();
}
outer1();
function outer2(){
alert("use outer2")
}
//use inner1,use inner2,use outer2

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

再看一个例子:

 function A() {
setTimeout("var a=2;alert(a)", 1000);
}
A();
alert(a);//a is not define
==============================================
function A() {
setTimeout("var a=2;alert(a)", 1000);
alert(a);//a is not define
}
A();
============================================
function A() {
eval("var a=2;alert(a)", 1000);
alert(a);//
}
A();
============================================
function A() {eval("var a=2;alert(a)", 1000);}
A();
alert(a);//a is not define
============================================
function A() {window.eval("var a=2;alert(a)", 1000);}
A();
alert(a);//
============================================
function A() {window.eval("var a=2;alert(a)", 1000);alert(a);//a is not define}
A();

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

 <script language="javascript" type="text/javascript">
var a=1;
eval('var a=2;alert(a)');
alert(a);
setTimeout('alert(a)',1000);
</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(); // 1
eval('x = 2', bar); // 传入上下文,影响了内部的var x 变量
bar(); // 2
 最后一个非常值得注意的地方是eval既是ECMAScript的关键字有时window的一个属性,在运用的时候要注意以下的问题:
 function test(){
eval('var a=10;')
alert(a);//
}
test();
--------------------------------------------------------------------
function test(){
eval('var a=10;')
}
test();
alert(a);//a is not defined
--------------------------------------------------------------------
function test(){
window.eval('var a=10;')
}
test();
alert(a);//
--------------------------------------------------------------------
function test(){
var val=eval;
val('var a=10;')
}
test();
alert(a);//

对setTimeout()第一个参数是字串的深入理解以及eval函数的理解的更多相关文章

  1. setTimeout 第一个参数类型

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

  2. python-Levenshtein几个计算字串相似度的函数解析

    linux环境下,没有首先安装python_Levenshtein,用法如下: 重点介绍几个该包中的几个计算字串相似度的几个函数实现. 1. Levenshtein.hamming(str1, str ...

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

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

  4. JS的setTimeout函数第一个参数问题

    setTimeout的第一个参数只能放一个无参的函数,更像放了一个函数指针在那里,如果要放带参数的话,就要拿个匿名函数包裹一下

  5. setTimeout中第一个参数

    永远不要传递字符串作为setTimeout的第一个参数!!!记住第一个参数只允许函数,或者匿名函数!因为传递字符串有陷阱啊!!它就是披着羊皮的eval啊!!而且上下文会变成全局啊!! 第一个参数为可执 ...

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

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

  7. 字串符相关 split() 字串符分隔 substring() 提取字符串 substr()提取指定数目的字符 parseInt() 函数可解析一个字符串,并返回一个整数。

    split() 方法将字符串分割为字符串数组,并返回此数组. stringObject.split(separator,limit) 我们将按照不同的方式来分割字符串: 使用指定符号分割字符串,代码如 ...

  8. [洛谷P1032] 字串变换

    洛谷题目链接:字串变换 题目描述 已知有两个字串 A, B 及一组字串变换的规则(至多6个规则): A1 -> B1 A2 -> B2 规则的含义为:在 A$中的子串 A1 可以变换为 B ...

  9. POJ - 2774~POJ - 3415 后缀数组求解公共字串问题

    POJ - 2774: 题意: 求解A,B串的最长公共字串 (摘自罗穗骞的国家集训队论文): 算法分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长 公共子串等价于求 ...

随机推荐

  1. 020自动化测试 PK 手动测试

    一.手工测试为什么不可替代 手工测试是不可替代的,因为人是具有很强只能判断能力的,而工具是相对机械缺乏思维能力的东西 工具是人开发出来的 二.手工测试不可替代的表现 测试用例的设计:需要tester有 ...

  2. H5制作1--母亲节快乐

    H5作品现在很流行额. 早上起的很早.就自己试着去了解了一下.感觉很easy. 用了百度的H5在线制作工具.感觉很easy.顺便给百度做下推广吧.h5.baidu.com 于是就有了自己的第一个dem ...

  3. C/C++编译预处理命令详解【转】

    1.       预处理程序  按照ANSI标准的定义,预处理程序应该处理以下指令: #if #ifdef #ifndef #else #elif #endif #define #undef #lin ...

  4. 【转载】sed命令详解

    [转载自]http://www.cnblogs.com/edwardlost/archive/2010/09/17/1829145.html   sed -i  把后面的操作后的文本输出回原文本   ...

  5. 深度学习 CNN CUDA 版本2

    作者:zhxfl 邮箱:zhxfl##mail.ustc.edu.cn 主页:http://www.cnblogs.com/zhxfl/p/4155236.html 第1个版本blog在这里:http ...

  6. HDU-4687 Boke and Tsukkomi 带花树,枚举

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4687 题意:给一个无向图,求所有的最大匹配的情况所不包含的边.. 数据比较小,直接枚举边.先求一次最大 ...

  7. HDU5781--ATM Mechine(概率dp)

    题意:Alice忘记了自己银行里存了多少钱,只记得在[0,k]之间.每次取钱如果余额足够就出钱,否则警告一次,警告超过w次就会把你抓起来,在不想被警察抓起来的前提下,Alice采取最优策略,求期望取钱 ...

  8. .NET通用基本权限系统

    DEMO下载地址: http://download.csdn.net/detail/shecixiong/5372895 一.开发技术:B/S(.NET C# ) 1.Windows XP以上 (支援 ...

  9. 偶遇mysql外键不好使

    原来是创建表时选择的类型不一样,应该是innoDB,而且关联的主表类型也必须是innoDB

  10. js难点之闭包理解

    如何从外部读取局部变量? 闭包就是能够读取其他函数内部变量的函数. 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”. 所以 ...