eval 的那些事儿~~
买了 [JavaScript语言精髓与编程实践],这几天天天在看….
也看了书的作者的BLOG,具体帖子:
http://blog.csdn.net/aimingoo/archive/2008/07/22/2692512.aspx
以下谈谈针对上帖的学习感受..
“声明语句”是不返回值的
对这句话的理解非常关键,否则看帖子会完全没有思路,完全不必要再看下去。
首先什么事 声明语句?
在JSCRIPT手册上 对于var有这样的解释 :
[var 语句
声明变量。]
var a=100;
var t={};
var u=[1,2,3];
这些都是声明语句。声明语句是在语法解释期,由预编译器处理的,比如
alert(n);
var n=10;
这在浏览器中会显示出“undefined”,而不是报错。原因还是因为“声明语句是在语法解释期,由预编译器处理的”,所以执行语句的时候,尽管在代码的物理位置上,var n在alert(n)的上面。但是还是会知道已经声明了n.
这和赋值语句是不一样的。
赋值语句 n=10;这种语句只会在执行期执行。而不会预先声明。有返回值,为最右边的10
对于function x() {}
称为具名函数的“声明语句”。
所以:
var func = eval("function u(){}");
var func = eval("var c=100");
都返回 undefined;
但是 如果是 var func = eval("(function u(){})");
在引号后面加上了()后,情况就变得有些“显得复杂了“。
括号()有运算符的意思。表示强制优先运算。比如5+7*10 与(5+7)*12。
所以加了括号之后,就成了表达式了。而非声明语句。
因为 “eval()的返回值,其实是语句最后一个(有效的)子句的返回值。“
所以加了括号之后,成了一个函数表达式。总之不是一个声明语句(函数声明)。所以浏览器[FIREFOX]显示为function u() {} ;
但是在以JSCRIPT为核心的IE中,情况却并非这样。
IE中还是认为这是一个函数声明。事实上IE确实把u被声明了,而在FF里没有声明(不可能在“表达式”中出现“语句声明”) ,所以在IE中任然显示undefined.
而在帖子的末尾, 说是在括号里加上运算符就真正的是语句了。
var func = eval("(1, function(){})");
alert(func); // 显示"function(){}" 在这里又是表达式,又是声明语句。
总结起来:
声明语句”是不返回值的,也就是返回undefined
eval()的返回值,其实是语句最后一个(有效的)子句的返回值。
其实这种技术很可能没有一点用处,但是用来锻炼分析问题的能力也还是不错的,同时也告诉自己尽量避免简单的事情做得复杂不可预见。