词法作用域之欺骗词法
来源:互联网 发布:催收数据安全管理制度 编辑:程序博客网 时间:2024/04/30 06:51
如果词法作用域完全由写代码期间函数所声明的位置来定义,怎样才能在运行时来“修改”(欺骗)词法作用域。
有两种机制来实现这个目的,但最好不要使用,欺骗词法作用域会导致性能下降。
1. eval
eval函数可以接受一个字符串为参数,并将其中的内容视为好像在书写时就存在于程序中这个位置的代码。
function foo(str,a){ eval(str);//欺骗 console.log(a,b);}var b=2;foo("var b=3;",1);//1,3
在严格模式的程序中,eval()在运行时有其自己的词法作用域,意味着其中的声明无法修改所在的作用域。
function foo(str){ "use strict"; eval(str); console.log(a);//ReferenceError:a is not defined}foo("var a=2;");
2. with
with通常被当作重复引用同一个对象中的多个属性的快捷方式,可以不需要重复引用对象本身。
var obj={ a:1, b:2, c:3}//单调乏味的重复obj.a=2;obj.b=3;obj.c=4;//简单的快捷方式with(obj){ a=3; b=4; c=5; d=6;//obj中无d,所以在全局作用域上创建d=6.}
但实际上这不仅仅是为了方便的访问对象属性。
function foo(obj){ with(obj){ a=2; }}var o1={ a:3};var o2={ b:3};foo(o1);console.log(o1.a);//2foo(o2);console.log(o2.a);//undefinedconsole.log(a);//2---a被泄漏到全局作用域上了
当传o1给with时,with所声明的作用域是o1,而这个作用域中含有一个同o1.a属性相符的标识符。当o2作为作用域时,其中并没有a标识符,因此进行了正常的LHS标识符查找,依次是o2作用域、foo()作用域和全局作用域中都没有找到标识符a,所以当a=2执行时,自动创建了一个全局变量(非严格模式)。如果在foo()作用域中找到了a,就会改变foo()作用域中a的值。
严格模式下with被完全禁止,而保留核心功能的前提下,间接或非安全的使用eval()也被禁止了。
使用其中任何一个机制都将导致代码运行变慢。不要使用它们。
阅读全文
0 0
- 词法作用域之欺骗词法
- 欺骗词法
- 作用域之词法作用域
- Javascript词法作用域
- Javascript 词法作用域
- JS词法作用域
- 再谈闭包-词法作用域
- 词法作用域
- 词法作用域
- 词法作用域
- JavaScript 词法作用域
- 词法作用域
- 词法作用域
- JavaScript-词法作用域
- JS闭包之词法作用域
- JS闭包之词法作用域
- JavaScript高级之词法作用域和作用域链
- 进击JavaScript之词法作用域与作用域链
- 我的改编古诗
- 用bochs调试mbr--开始调试啦
- Error:Gradle distribution 'https://services.gradle.org/distributions/gradle-3.3-all.zi
- Problem 1002 cable cable cable-2017 ACM/ICPC Asia Regional Shenyang Online
- ImageLoader的默认配置
- 词法作用域之欺骗词法
- poj3237 Tree(树链剖分)
- 转时间复杂度和空间复杂度详解
- Leetcode :2 Add Two Numbers
- XListView上拉加载下拉刷新
- 第四章 分治策略
- Fast Input
- CSS实现多栏布局的几种方式
- G