JavaScript学习小结之被嫌弃的eval函数和with语句实例详解


Posted in Javascript onAugust 01, 2016

前面的话

eval和with经常被嫌弃,好像它们的存在就是错误。在CSS中,表格被嫌弃,在网页中只是用表格来展示数据,而不是做布局,都可能被斥为不规范,矫枉过正。那关于eval和with到底是什么情况呢?本文将详细介绍eval()函数和with语句

eval

定义

eval()是一个全局函数,javascript通过eval()来解释运行由javascript源代码组成的字符串

var result = eval('3+2');
console.log(result,typeof result);//5 'number'

用法

eval()只有一个参数,如果传入的参数不是字符串,它直接返回这个参数。如果参数是字符串,它会把字符串当成javascript代码进行编译。如果编译失败则抛出一个语法错误(syntaxError)异常。如果编译成功,则开始执行这段代码,并返回字符串中的最后一个表达式或语句的值,如果最后一个表达式或语句没有值,则最终返回undefined。如果字符串抛出一个异常,这个异常将把该调用传递给eval()

var num = 1;
var str = 'test';
console.log(eval(num));//1
console.log(eval(str));//ReferenceError: test is not defined 
var strLong1 = 'var x = 1;var y = 2;';
console.log(eval(strLong1),x,y);//undefined 1 2
var strLong2 = 'var x = 1; x++;';
console.log(eval(strLong2),x);//1 2

作用域

eval()使用了调用它的变量作用域环境。也就是说,它查找变量的值和定义新变量和函数的操作和局部作用域中的代码完全一样

var b = 2;
function foo(str,a){
eval(str);
console.log(a,b);
}
foo('var b = 3;',1);//1 3

别名

当通过别名调用时,eval()会将其字符串当做顶层的全局代码来执行。执行的代码可能会定义新的全局变量和全局函数,或者给全局变量赋值,但却不能使用或修改函数中的局部变量

var geval = eval; 
var x = 'global',y = 'global'; 
function f(){
var x = 'local';
eval('x += "changed";');
return x;
}
function g(){
var y = 'local';
geval('y += "changed";');
return y;
}
console.log(f(),x);//localchanged global
console.log(g(),y);//local globalchanged

[注意]IE8-浏览器通过别名调用eval()和正常调用eval()的结果相同

副作用

javascript解释器进行了大量的代码分析和优化。而eval()的问题在于,用于动态执行的代码通常不能分析,于是解释器也无法对其进行优化,这会导致性能下降

与eval()类似的有setTimeout()、setInterval()、new Function()等,这些函数都可以以字符串作为参数,在程序运行时动态执行。这种执行机制带来的好处无法抵消其性能上的损失,所以应该尽量避免使用

严格模式

由于eval()函数过于强大,严格模式对其进行了严格的限制

【1】不能通过eval()函数来创建变量或函数,但可以查询和更改其值

'use strict';
eval('var x = 1;');
console.log(x);//ReferenceError: x is not defined
'use strict';
var x = 1;
eval('x = 2;');
console.log(x);//2

【2】禁止使用eval作为标识符

'use strict';
var eval = 10;//SyntaxError: Unexpected eval or arguments in strict mode

with

定义with语句的目的主要是为了简化多次编写同一对象的工作

with语句将object添加到作用域链的头部,然后执行statement,最后把作用域链恢复到原始状态

with(object){
statement;
}

作用

在对象嵌套层次很深的时候通常会使用with语句来简化代码编写。而本质上是通过将一个对象的引用当作作用域来处理,将对象的属性当作作用域中的标识符来处理,从而创建了一个新的词法作用域

在客户端javascript中,可能会使用类似下面这种表达式来访问一个HTML表单中的元素

document.forms[0].address.value

如果这种表达式在代码中多次出现,则可以使用with语句将form对象添加到作用域链的顶层

with(document.forms[0]){
name.value = '';
address.value = '';
emai.value = '';
}

这种方法减少了大量的输入,不用再为每个属性名添加document.forms[0]前缀。这个对象临时挂载在作用域链上,当javascript需要解析诸如address的标识符时,就会自动在这个对象中查找

[注意]with语句提供了一种读取对象的属性的快捷方式,但它并不能创建对象的属性

如果对象o有一个属性x,那么下面代码给这个属性赋值为1

var o = {x:0};
with(o) x = 1;
console.log(o.x);//1

如果o中没有定义属性x,下面代码和不使用with语句的代码x=1是一模一样的。这是因为对变量x进行了LHS查询,并将1赋值给它

var o = {};
with(o) x = 1;
console.log(o.x);//undefined
console.log(x);//1

副作用

与eval类似,with语句的javascript代码非常难于优化,同时也会给调试代码造成困难,并且同没有使用with语句的代码相比,它运算得更慢

而且,如果with语句不当,还有可能造成变量泄漏,污染全局作用域的情况

var x = 1;
var o = {};
with(o){
x = 2;
}
console.log(x);//2
console.log(o.x);//undefined

严格模式

严格模式下,禁止使用with语句

//SyntaxError: Strict mode code may not include a with statement
'use strict';
var o = {};
with(o){
x = 2;
}

最后

使用eval和with会使得引擎无法在编译时对作用域查找进行优化,从而导致性能下降,代码运行变慢。因为eval和with在实际工作中很少使用,所以严格模式下的限制,对我们来说影响不大。就像比如外交部某一天发布公告,我国不再发放去牙买加的签证,牙买加虽然都听过,但大多数人这辈子都可能不去一回,所以,无所谓了。同样地,eval和with被嫌弃不嫌弃的,也是无所谓了

以上所述是小编给大家介绍的JavaScript学习小结之被嫌弃的eval函数和with语句实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Mootools 1.2教程 正则表达式
Sep 15 Javascript
JS正则表达式大全(整理详细且实用)
Nov 14 Javascript
js加载读取内容及显示与隐藏div示例
Feb 13 Javascript
jquery实现一个简单好用的弹出框
Sep 26 Javascript
js实现简单选项卡与自动切换效果的方法
Apr 10 Javascript
jQuery实现鼠标划过修改样式的方法
Apr 14 Javascript
JQuery手速测试小游戏实现思路详解
Sep 20 Javascript
JavaScript中省略元素对数组长度的影响
Oct 26 Javascript
jquery手机触屏滑动拼音字母城市选择器的实例代码
Dec 11 jQuery
vue监听dom大小改变案例
Jul 29 Javascript
结合axios对项目中的api请求进行封装操作
Sep 21 Javascript
vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案
Mar 01 Vue.js
jQuery简单设置文本框回车事件的方法
Aug 01 #Javascript
AngularJS基础 ng-csp 指令详解
Aug 01 #Javascript
AngularJs页面筛选标签小功能
Aug 01 #Javascript
Bootstrap Table使用方法详解
Aug 01 #Javascript
jQuery实现表格行和列的动态添加与删除方法【测试可用】
Aug 01 #Javascript
Angular 页面跳转时传参问题
Aug 01 #Javascript
AngularJS基础 ng-copy 指令实例代码
Aug 01 #Javascript
You might like
用PHP代码在网页上生成图片
2015/07/01 PHP
详解PHP的Yii框架中扩展的安装与使用
2016/04/01 PHP
微信支付开发动态链接Native支付
2016/07/12 PHP
PHP 中TP5 Request 请求对象的实例详解
2017/07/31 PHP
让iframe自适应高度(支持XHTML,支持FF)
2007/07/24 Javascript
actionscript与javascript的区别
2011/05/25 Javascript
JavaScript 选中文字并响应获取的实现代码
2011/08/28 Javascript
js滚动条平滑移动示例代码
2016/03/29 Javascript
AngularJS入门教程之更多模板详解
2016/08/19 Javascript
Vim快速合并行及vim 将文件所有行合并到一行
2017/11/27 Javascript
nodejs搭建本地服务器轻松解决跨域问题
2018/03/21 NodeJs
Node.js应用设置安全的沙箱环境
2018/04/23 Javascript
Node.js模拟发起http请求从异步转同步的5种用法
2018/09/26 Javascript
点击按钮弹出模态框的一系列操作代码实例
2019/03/29 Javascript
Vue源码探究之虚拟节点的实现
2019/04/17 Javascript
OpenLayers3实现图层控件功能
2020/09/25 Javascript
基于JavaScript实现简单扫雷游戏
2021/01/02 Javascript
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
Python的Flask框架应用调用Redis队列数据的方法
2016/06/06 Python
Python判断变量是否为Json格式的字符串示例
2017/05/03 Python
Python实现PS滤镜功能之波浪特效示例
2018/01/26 Python
在Python中增加和插入元素的示例
2018/11/01 Python
Python docx库用法示例分析
2019/02/16 Python
python进程的状态、创建及使用方法详解
2019/12/06 Python
TensorFlow实现打印每一层的输出
2020/01/21 Python
CSS去掉A标签(链接)虚线框的方法
2014/04/01 HTML / CSS
Talbots官网:美国成熟女装品牌
2019/11/15 全球购物
巴西葡萄酒商店:Divvino
2020/02/22 全球购物
中文系学生自荐信范文
2013/11/13 职场文书
秋季红领巾广播稿
2014/01/27 职场文书
应届毕业生应聘自荐信范文
2014/02/26 职场文书
建筑管理专业求职信
2014/07/28 职场文书
2014年党员评议表自我评价
2014/09/27 职场文书
警察正风肃纪剖析材料
2014/10/16 职场文书
计生个人工作总结
2015/02/28 职场文书
公司规章制度范本
2015/08/03 职场文书