php外包、微信开发、app开发尽在蓝普!PHP技术服务商

eval 命令的作用

eval命令的作用是,将字符串当作语句执行。

eval('var a = 1;');
a // 1

上面代码将字符串当作语句运行,生成了变量a

放在eval中的字符串,应该有独自存在的意义,不能用来与eval以外的命令配合使用。举例来说,下面的代码将会报错。

eval('return;');

eval没有自己的作用域,都在当前作用域内执行,因此可能会修改当前作用域的变量的值,造成安全问题。

var a = 1;
eval('a = 2');

a // 2

上面代码中,eval命令修改了外部变量a的值。由于这个原因,eval有安全风险。

为了防止这种风险, 规定,如果使用严格模式,eval内部声明的变量,不会影响到外部作用域。

( f() {
  'use strict';
  eval('var foo = 123');
  console.log(foo);  // ReferenceError: foo is not defined
})()

上面代码中,函数f内部是严格模式,这时eval内部声明的foo变量,就不会影响到外部。

不过,即使在严格模式下,eval依然可以读写当前作用域的变量。

(function f() {
  'use strict';
  var foo = 1;
  eval('foo = 2');
  console.log(foo);  // 2
})()

上面代码中,严格模式下,eval内部还是改写了外部变量,可见安全风险依然存在。

此外,eval的命令字符串不会得到 JavaScript 引擎的优化,运行速度较慢。这也是一个不应该使用它的理由。

通常情况下,eval最常见的场合是解析 数据字符串,不过正确的做法应该是使用浏览器提供的JSON.parse方法。

JavaScript 引擎内部,eval实际上是一个引用,默认调用一个内部方法。这使得eval的使用分成两种情况,一种是像上面这样的调用eval(expression),这叫做“直接使用”,这种情况下eval的作用域就是当前作用域。除此之外的调用方法,都叫“间接调用”,此时eval的作用域总是全局作用域。

var a = 1;

function f() {
  var a = 2;
  var e = eval;
  e('console.log(a)');
}

f() // 1

上面代码中,eval是间接调用,所以即使它是在函数中,它的作用域还是全局作用域,因此输出的a为全局变量。

eval的间接调用的形式五花八门,只要不是直接调用,都属于间接调用。

eval.call(null, '...')
window.eval('...')
(1, eval)('...')
(eval, eval)('...')

上面这些形式都是eval的间接调用,因此它们的作用域都是全局作用域。

eval作用类似的还有Function构造函数。利用它生成一个函数,然后调用该函数,也能将字符串当作命令执行。

var  = 'foo({"id": 42})';

var f = new Function( 'foo', jsonp );
// 相当于定义了如下函数
// function f(foo) {
//   foo({"id":42});
// }

f(function (json) {
  console.log( json.id ); // 42
})

上面代码中,jsonp是一个字符串,Function构造函数将这个字符串,变成了函数体。调用该函数的时候,jsonp就会执行。这种写法的实质是将代码放到函数作用域执行,避免对全局作用域造成影响。

不过,new Function()的写法也可以读写全局作用域,所以也是应该避免使用它。

标签:, , ,

转载请注明来源蓝普网络并以链接形式标明本文地址
本文链接: http://www.wbphp.cn/html/y05/15190.html

作者:胡, 金乐 | 日期:2018-05-12 | 分类:心情日记 | 评论:0 条 | 浏览:4


上一篇:
下一篇:

发表评论

*

* 以便邮件回复


给我汇款 | 合作流程 | 看看我们 | 加入我们 Copyright 2008-2016 php外包与洛阳php培训服务商. Some Rights Reserved. 豫ICP备12025288号-1