资讯专栏INFORMATION COLUMN

JS学习笔记 - eval() 是魔鬼

mengera88 / 478人阅读

摘要:要牢记使用这些构造函数来传递参数,在大部分情况下,会导致类似的隐患,因此应该也尽量避免使用这些函数。下面一个栗子使用构造函数和是比较类似的,因此该函数的使用也需要十分小心。

  

本文章记录本人在学习 JavaScript 中看书理解到的一些东西,加深记忆和并且整理记录下来,方便之后的复习。

小白使用 eval()

如果在代码中使用了eval(),请记住一句话:“eval()是一个魔鬼”。该函数可以将任意的字符串当做一个js代码来执行。当需要讨论的代码是预先编译好了(不是在动态运行时候决定),是没有理由使用eval()的。例如,如果你知道点表示法,但是不知道下表表示法的情况(下面一个栗子)。

eval("myValue = myObject." + myKey + ";");

而不是这样写(下面一个栗子)。

myValue = MyObject[myKey];
安全隐患

使用eval()是有一些安全隐患的,因为这样做有可能执行被篡改过的代码(例如来自网络的代码)。这是在处理来自一个Ajax请求的JSON响应时候常见的反模式。在那些情景下,最好是使用浏览器内置的方法来解析JSON请求,以确保安全性和有效性。

还有eval()函数还减弱了应用程序的安全性,因为他给被请求的文本赋予了太多的权力,而且就像with语句执行的方式一样,它降低了语言的性能。

定时器

在编写js特效的时候,会常用setTimeout、setInterval()方法。要牢记使用这些构造函数来传递参数,在大部分情况下,会导致类似eval()的隐患,因此应该也尽量避免使用这些函数。(下面一个栗子)

// bad
setTimeout("myFunc()", 1000);
setInterval("myFunc(1, 2, 3)", 1000);

// good
setTimeout(myFunc, 1000);
setInerval(function(){
    myFunc(1, 2, 3);
}, 1000);
new Function()

使用new Function()构造函数和eval()是比较类似的,因此该函数的使用也需要十分小心。该函数是一个功能强大的函数,但是通常容易被误用。如果一定要使用eval()的话,可以考虑是new Function()来代替eval()。这样做的一个潜在的好处就是由于在new Function()中的代码将在局部变量函数空间中运行,因此代码中任何采用var定义的变量不会自动成为全局变量(下面一个栗子)。

console.log(typeof un); // undefined
console.log(typeof deux); // undefined
console.log(typeof trois); // undefined

var jsstring = "var un = 1; console.log(un);"
eval(jsstring); // 1

jsstring = "var deux = 2; console.log(deux);"
eval(jsstring); // 2

jsstring = "var deux = 2; console.log(deux);"
(function(){
    eval(jsstring);
}()); // 3

console.log(typeof un); // number
console.log(typeof deux); // undefined
console.log(typeof trois); // undefined

还有就是eval()是会影响到作用域链的,而Function更像一个沙盒。无论在那里执行Function,它都仅仅能看到全局作用域。因此对局部变量的影响比较小(下面一个栗子)。

(function(){
    var local = 1;
    eval("local = 3; console.log(local)");
    console.log(local); // 3
}());

(function(){
    var local = 1;
    Function("console.log(typeof local);")(); // undefined
}());
严格模式下的 eval()

来自MDN:在严格模式下 eval 仅仅为被运行的代码创建变量, 所以 eval 不会影响到名称映射到外部变量或者其他局部变量(下面一个栗子)。

var x = 17;
var evalX = eval(""use strict"; var x = 42; x");
assert(x === 17);
assert(evalX === 42);

更多的详细内容:严格模式 MDN

  

最后,如果文章有什么错误和疑问的地方,请指出。与sf各位共勉!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85762.html

相关文章

  • eval()不魔鬼,只被误解了(翻译)

    摘要:因为道格拉斯的大多数作品并没有注明日期,所以,我不确定他是否是在年创造了这个术语。但这并不能说明是魔鬼,这只是开发工作流程中的一点问题。中间人攻击被认为是的永远存在的危险,会受到蠕虫的的攻击。 原文来自:https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/ 作者:Nicholas C.Z...

    elarity 评论0 收藏0
  • 在编写javascript时要注意的一些细节

    摘要:不单单是因为引起的。用与要注意的地方这里要注意的是这二个函数的第一个参数都会把指向还有第一个参数可以为但不要这样用因为这样等于自己隐式使用了。 自动分号插入 Js不像其他语言强制要求;号结尾不然编译不过,原因是JS有自动;号的插入。 var text=function(){} text() 这样你不加;号也能运行其实在内部js是需要;号去帮助解析的 var text=function(...

    Eric 评论0 收藏0
  • 前端性能优化(JavaScript篇)

    摘要:像也是类似的也不建议使用,会降低性能,通过包裹的代码块,作用域链将会额外增加一层,降低索引效率对象的优化缓存需要被使用的对象获取数据的性能有如下顺序从快到慢变量获取数组下标获取对象的整数索引获取对象属性获取对象非整数索引获取。 正巧看到在送书,于是乎找了找自己博客上记录过的一些东西来及其无耻的蹭书了~~~ 小广告:更多内容可以看我的博客 优化循环 如果现在有个一个data[]数组...

    KunMinX 评论0 收藏0
  • 前端性能优化(JavaScript篇)

    摘要:像也是类似的也不建议使用,会降低性能,通过包裹的代码块,作用域链将会额外增加一层,降低索引效率对象的优化缓存需要被使用的对象获取数据的性能有如下顺序从快到慢变量获取数组下标获取对象的整数索引获取对象属性获取对象非整数索引获取。 正巧看到在送书,于是乎找了找自己博客上记录过的一些东西来及其无耻的蹭书了~~~ 小广告:更多内容可以看我的博客 优化循环 如果现在有个一个data[]数组...

    kun_jian 评论0 收藏0
  • JSON学习笔记(一)

    先学习阮大神的 数据类型和Json格式 一、js中解析JSON的方式 eval() JSON.parse var jsondata = {staff:[{name:小红,age:16},{name:小明,age:20},{name:小芳,age:18}]} var jsonobj = eval(( + jsondata + )) alert( jsonobj.staff[0].name); s...

    Scott 评论0 收藏0

发表评论

0条评论

mengera88

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<