7.25笔记《你不知道的javascript》词法作用域
2017-07-25 本文已影响0人
遨游在bug中
<script>
function foo(a){//a=2
//定义局部变量 b = 2*2 ;b实际 = 4;
var b = a*2;
//内部函数
function bar(c){//这里c = 12;
//打印a,b,c( 2, 4, 12)
console.log(a,b,c);
/*查找
执行console.log(...)声明,并查找a,b,c三个变量的引用。
它首先从最内部的作用域bar()函数的作用域开始查找。
开始查找a,bar内部没有,所以它就去上一级foo()函数作用域查找,
找到了a并确定了值,b同理。对于c来说就在bar内部,不需要往上一级查找;
作用域查找会在找到第一个匹配的标识符时停止;
在多层的嵌套作用域中可以定义同名的《标识符》,这叫做‘遮蔽效应’
(内部的标识符‘遮蔽’了外部的标识符)。抛开遮蔽效应,作用域查找
始终从运行时所处的最内部作用域开始,逐级向外查找,直到查到第一个标识符为止。
*/
}
bar(b*3);//调用bar函数传入 b = 4*3;b = 12;
}
foo(2);//调用函数foo传入参数2;第二步:执行foo函数内部函数bar的方法打印出a,b,c
/*
首先,这个例子中有三个嵌套作用域
1.包含foo函数的-全局作用域;
2.包含着 变量a,变量b以及函数bar的 - foo函数作用域;
3.包含着只有 变量c的函数 - bar作用域
*/
</script>
<script>
//欺骗词法作用域
function foo2(str,a){
eval(str);//欺骗
console.log(a,b)
}
var b = 2;
foo2('var b = 3;',1)//1,3
//eval(...)调用中的var b = 3 ,这段代码会被当成本来就在那,
//重新声明的b会覆盖全局声明var b = 2;这段代码实际在foo2(...)
//函数作用域中创建了一个变量b,从而遮蔽全局作用域的同名变量。
//不推荐使用,同样with也不推荐使用。因为看这个肯定还是弱鸡,并不能用好。
</script>
<!-- 小结 -->
<!--
词法作用域是由写代码时函数声明的位置来决定的,
javascript中有两个机制可以‘欺骗’词法作用域:
eval()和with,前者可以对一段包含一个或多个声明的代码
‘字符串’进行演算,借此修改已经存在的词法作用域(在运行时);
with本质是是通过将一个对象的引用当做作用域来处理,将对象的
属性当做作用域中的标识符来处理,从而创建一个新的词法作用域;
这两个都存在严重问题,当你还不是大佬的时候请谨慎使用。
-->