前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >词法作用域

词法作用域

作者头像
用户3258338
发布2019-12-10 16:23:28
5500
发布2019-12-10 16:23:28
举报
文章被收录于专栏:女程序员的日常_Lin

是不是有时候我太理性了?


我的同事说这个猫的眼神像我。我要是如我猫这般可爱多好啊~

1. 词法阶段


大部分标准语言编译器的第一个工作阶段叫做词法化。词法化的过程会对源代码中的字符进行检查,如果是有状态的解析过程,还会赋予单词语义。

词法作用域就是定义在词法阶段的作用域。词法作用域是由你在写代码时将变量和块作用域下载哪里来决定的。

  • 作用域查找会在找到第一个匹配的标识符时停止。在多层的嵌套作用域中可以定义同名的标识符,这叫做“遮蔽效应”。
  • 无论函数在哪里被调用,他的词法作用域只由函数被声明时所处的位置决定。
  • 词法作用域查找只会查找一级标识符。如果代码引用了foo.bar.baz,词法作用域查找只会试图查找foo标识符,找到变量后,对象属性访问规则会分别接管对bar和baz属性的访问。

2. 欺骗词法(修改词法作用域)


欺骗词法作用域会导致性能下降。

两种欺骗词法作用域的机制:

2.1 eval

eval()函数接受一个字符串为参数,并将其中的内容视为在书写时就存在于程序中这个位置的代码。

代码语言:javascript
复制
function foo(str, a) { 
  eval( str ); // 欺骗! 
  console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // 1, 3

这段代码在foo()内部创建了一个变量b,遮蔽了外部的b。

在程序中动态生成代码的使用场景非常罕见,因为它带来的好处无法抵消性能上的损失。

2.2 with

eval通常被当做重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。

比如:

代码语言:javascript
复制
var obj = {
  a : 1,
  b : 2,
  c : 3  
}
// 修改obj的值
obj.a = 2;
obj.b = 3;
obj.a = 4;
// 快捷方式
with(obj){
  a = 1;
  b = 4;
  c = 5;
}

但是,看看下面的代码:

代码语言:javascript
复制
function foo(obj) { 
  with (obj) {
    a = 2; 
  }
}
var o1 = { 
  a: 3
};
var o2 = { 
  b: 3
};
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2——不好,a 被泄漏到全局作用域上了!

当我们传递 o1 给 with 时,with 所声明的作用域是 o1,而这个作用域中含 有一个同 o1.a 属性相符的标识符。但当我们将 o2 作为作用域时,其中并没有 a 标识符, 因此进行了正常的 LHS 标识符查找

有个副作用就是a=2赋值操作创建了一个全局的变量a。

尽管 with 块可以将一个对象处理为词法作用域,但是这个块内部正常的 var声明并不会被限制在这个块的作用域中,而是被添加到 with 所处的函数作 用域中。

  • eval()函数如果接受了含有一个或多个声明的代码,就会修改其所处的词法作用域,而with声明实际上是根据你传递给它的对象凭空创建一个全新的词法作用域。
  • eval()和with会被严格模式所影响,with被完全禁止,在保留核心功能的前提下,间接或者非安全的使用eval()也被禁止

3. 性能


JS引擎会在编译阶段进行数项的性能优化。其中有些依赖于能够根据代码的词法进行静态分析,并预先确定所有变量和函数的定义位置,才能在执行过程中快速找到标识符。

最悲观的情况是,如果出现eval()和with,所有的优化可能都是无意义的,因此最简单的做法就是不做任何优化。

so,不要使用他们!!!

愿我们有能力不向生活缴械投降---Lin

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 女程序员的日常 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档