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

 更新时间:2016年08月01日 11:01:46   作者:小火柴的蓝色理想  
这篇文章主要介绍了JavaScript学习小结之被嫌弃的eval和with实例详解的相关资料,需要的朋友可以参考下

前面的话

  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语句实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • JS中把函数作为另一函数的参数传递方法(总结)

    JS中把函数作为另一函数的参数传递方法(总结)

    下面小编就为大家带来一篇JS中把函数作为另一函数的参数传递方法(总结)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • 微信小程序实现列表左右滑动

    微信小程序实现列表左右滑动

    这篇文章主要为大家详细介绍了微信小程序实现列表左右滑动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-11-11
  • webpack构建打包的性能优化实战指南

    webpack构建打包的性能优化实战指南

    webpack是前端开发中比较常用的打包工具之一,另外还有gulp,grunt,下面这篇文章主要给大家介绍了关于webpack构建打包的性能优化的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-03-03
  • 在JavaScript 中按字母排序之如何在 JS 中按名称排序

    在JavaScript 中按字母排序之如何在 JS 中按名称排序

    有时你可能有一个单词数组,你想按字母顺序(从 a-z)对每个单词进行排序,或者你可能有一个包含用户信息(包括名字)的对象数组,例如,你想按照用户的名字来排序,接下来通过本文给大家介绍在JavaScript 中按字母排序之如何在 JS 中按名称排序,需要的朋友可以参考下
    2023-09-09
  • JavaScript直播评论发弹幕切图功能点集合效果代码

    JavaScript直播评论发弹幕切图功能点集合效果代码

    这篇文章主要介绍了JavaScript直播评论发弹幕切图功能点集合效果代码的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-06-06
  • JS highcharts动态柱状图原理及实现

    JS highcharts动态柱状图原理及实现

    这篇文章主要介绍了JS highcharts动态柱状图原理及实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • javascript格式化指定日期对象的方法

    javascript格式化指定日期对象的方法

    这篇文章主要介绍了javascript格式化指定日期对象的方法,涉及javascript针对日期对象操作的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • 新手如何快速理解js异步编程

    新手如何快速理解js异步编程

    这篇文章主要介绍了新手如何快速理解js异步编程,异步编程从早期的 callback、事件发布\订阅模式到 ES6 的 Promise、Generator 在到 ES2017 中 async,看似风格迥异,但是还是有一条暗线将它们串联在一起的,,需要的朋友可以参考下
    2019-06-06
  • JavaScript中的迭代器和可迭代对象与生成器

    JavaScript中的迭代器和可迭代对象与生成器

    这篇文章主要介绍了JavaScript中的迭代器和可迭代对象与生成器,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • js函数和this用法实例分析

    js函数和this用法实例分析

    这篇文章主要介绍了js函数和this用法,结合实例形式分析了js函数和this基本功能、原理、使用方法与操作注意事项,需要的朋友可以参考下
    2020-03-03

最新评论