对setTimeout()第一个参数是字串的深入理解以及eval函数的理解
<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函数的理解的更多相关文章
- setTimeout 第一个参数类型
读别人代码的时候看到这么一段,很不理解,然后就搜了一下百度 setTimeout / setInterval 第一个参数可以有三种类型: 字符串 . methods . 匿名函数 1.字符串 ...
- python-Levenshtein几个计算字串相似度的函数解析
linux环境下,没有首先安装python_Levenshtein,用法如下: 重点介绍几个该包中的几个计算字串相似度的几个函数实现. 1. Levenshtein.hamming(str1, str ...
- @有两个含义:1,在参数里,以表明该变量为伪参数 ,在本例中下文里将用@name变量代入当前代码中2,在字串中,@的意思就是后面的字串以它原本的含义显示,如果不
@有两个含义:1,在参数里,以表明该变量为伪参数 ,在本例中下文里将用@name变量代入当前代码中 2,在字串中,@的意思就是后面的字串以它原本的含义显示,如果不加@那么需要用一些转义符\来显示一些特 ...
- JS的setTimeout函数第一个参数问题
setTimeout的第一个参数只能放一个无参的函数,更像放了一个函数指针在那里,如果要放带参数的话,就要拿个匿名函数包裹一下
- setTimeout中第一个参数
永远不要传递字符串作为setTimeout的第一个参数!!!记住第一个参数只允许函数,或者匿名函数!因为传递字符串有陷阱啊!!它就是披着羊皮的eval啊!!而且上下文会变成全局啊!! 第一个参数为可执 ...
- 编程:使用递归方式判断某个字串是否回文(Palindrome)
Answer: import java.util.Scanner; public class Palindrome { private static int len;//全局变量整型数据 privat ...
- 字串符相关 split() 字串符分隔 substring() 提取字符串 substr()提取指定数目的字符 parseInt() 函数可解析一个字符串,并返回一个整数。
split() 方法将字符串分割为字符串数组,并返回此数组. stringObject.split(separator,limit) 我们将按照不同的方式来分割字符串: 使用指定符号分割字符串,代码如 ...
- [洛谷P1032] 字串变换
洛谷题目链接:字串变换 题目描述 已知有两个字串 A, B 及一组字串变换的规则(至多6个规则): A1 -> B1 A2 -> B2 规则的含义为:在 A$中的子串 A1 可以变换为 B ...
- POJ - 2774~POJ - 3415 后缀数组求解公共字串问题
POJ - 2774: 题意: 求解A,B串的最长公共字串 (摘自罗穗骞的国家集训队论文): 算法分析: 字符串的任何一个子串都是这个字符串的某个后缀的前缀. 求 A 和 B 的最长 公共子串等价于求 ...
随机推荐
- js实现收缩菜单效果
废话不多说,直接上代码: 有注释 <head> <title></title> <style type="text/css"> di ...
- PHP与MySQL动态网站开发1
PHP内嵌在HTML中,置于 <?php ?> 标签内 一般php文件扩展名.php 在body结算标签之前 对于远程服务器,可以用ftp工具传程序 打印语句 echo'Hello Wor ...
- HDU-4689 Derangement DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4689 题意:初始序列1,2...n,求所有满足与初始序列规定大小的错排数目.. 这道题目感觉很不错~ ...
- jQuery-menu-aim有時候不能觸發BUG解決辦法
在使用jQuery-menu-aim菜單時有時候鼠標移上去會發現樣式有改變但是第二階菜單卻沒有出現的問題 解決辦法:在exitMenu的方法中加入return true; 如下所示: exitMenu ...
- Fragment使用问题
1.Fragment嵌套Fragment,子fragment使用了viewpager,发现fragment不显示,解决方案如下 //使用下面代码 getChildFragmentManager(); ...
- 转载ASP.NET MVC 和ASP.NET Web Form简单区别
转载原地址 http://www.cnblogs.com/lei2007/p/3315431.html 概论: Asp.net 微软 提供web开发框架或者技术.分Web Form和ASP.NET ...
- Android 画图类View与SurfaceView之学习
在开发游戏开发中,android相应的提供了几个重要的模块: 1.显示界面的视图: Android 提供 View 和 SurfaceView 2.控制游戏整体结构: android 提供 Acti ...
- Java面试题集(51-70)
Java程序员面试题集(51-70) 51.类ExampleA 继承Exception,类ExampleB 继承ExampleA. 有如下代码片断: try{ thrownew ExampleB(“b ...
- ExtJs5.1.1使用中问题集锦
1.获取grid filter对象: grid.getStore().getFilters().items 2.获取grid filter后把filter对象转换成json格式字符串:grid.ge ...
- Python 调用C++
1.C++代码提供Python需要的接口: #include "stdafx.h" #include <boost/python.hpp> #include <s ...