作用域完全由写代码时的函数声明所决定,js有两种机制可以实现”破坏“我们对作用域的常规理解,通过eval()和with()。

1. eval()函数接受字符串为参数,并将其中的声明提升到eval()函数所在的位置。

 function foo(str,num) {
    eval(str);
    console.log(b,num);   //1,33
  }
  var b = 2;
  foo("var b = 1;",33);
  function foo(str,num) {
    console.log(b,num);   //2,33
  }
  var b = 2;
  foo("var b = 1;",33);

在严格模式的程序中,eval(...)函数在运行时有自己的作用域,即其中的申明无法修改所在的作用域。

 2. with()通常被当成引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。

  function foo(obj) {
    with(obj){
      a =5;
    var m = 20; }
  consloe.log(m); //20 }
var obj = { a:1 } foo(obj); console.log(obj.a); //5
with可以将一个或多个对象的属性处理为完全隔离的作用域。但是在with块内var申明的变量不会局限在这个块级作用域,而是被添加到with所处的函数作用域中。

这两个机制的副作用:引擎无法在编译的时候对作用域查找优化,使用其中的任何一种机制都会使代码运行变慢。

 

posted on 2017-12-06 23:24  sandy.simple  阅读(153)  评论(0编辑  收藏  举报