神奇的eval()与new Function()

原文链接:http://imys.net/20151222/eval-with-new-function.html

在需要兼容IE8以下的日子里,往往需要使用eval()来把后端传过来的JSON串转成可操作的JSON对象。直到昨天在翻看jQuery源码时,才发现jQuery.parseJSON的兼容实现用的是new Function()。马上Google了相关资料,寻找两者的区别。

eval

eval接受字符串参数,解析其中的js代码。如果编译失败,会抛出异常,否则执行其中的代码,计算返回值。

eval('2+2');  // 4

eval('console.log("ok")');  // ok

在实际应用中,通常这样转换JSON。

var jsonStr = '{ "age": 20, "name": "jack" }';
eval('(' + jsonStr + ')');

为什么要加括号呢?

因为js中{}通常是表示一个语句块,eval只会计算语句块内的值进行返回。加上括号就变成一个整体的表达式。

console.log( eval('{}') );      // undefind
console.log( eval('({})') );    // Object {}

使用eval需要注意执行作用域

var s = 1;
function a() {
    eval('var s=2');
    console.log(s);
}

a();                // 2
console.log(s);     // 1

在局部环境使用eval便会创建局部变量。可以显示指定eval调用者来改变上下文环境。

var s = 'global';
function a() {
    eval('var s = "local"');
    console.log(s);                 // local
    console.log(eval('s'));         // local
    console.log(window.eval('s'));  // global
}

Function

在之前我对于Function的了解只限于**“定义方法的一种非主流方式”**。却忽略了Function与eval相同的字符串参数特性。

语法:var func = new Function(arg1, arg2, ..., functionBody);

实例:

var add = new Function('a', 'b', 'return a+b;');
console.log( add(2, 3) );    // 5

由于其形参使用字符串的方式表示,也可以使用1个字符串来描述多个形参。

var add = new Function('a, b', 'return a+b;');
console.log( add(2, 3) );    // 5

在转换JSON的实际应用中,只需要这么做。

var jsonStr = '{ "age": 20, "name": "jack" }',
    json = (new Function('return ' + jsonStr))();

eval 与 Function 都有着动态编译js代码的作用,但是在实际的编程中并不推荐使用。如果可以,请用更好的方法替代。

在一些特殊的运用场合,也有一些合理运用的实践。比如模板解析等。

那么为什么 jQuery 要用new Function而不用eval呢?
看看老外做的两者以及原生方法的性能比较:JSON Performance comparison of eval, new Function and JSON

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值