JavaScript深入之词法作用域和动态作用域
var a = 10;
var o = {
a:11,
b:{
fn:function(){
console.log(a);
}
}
}
o.b.fn();
结果是 10 ,因为变量 a 并不能读取到对象 o 的属性 a ,如果 console.log(o.a),就会打印 11,函数 fn 的作用域链为 [AO, Global.VO],而 Global.VO 中包括了变量 a 和变量 o。
var value = 1;
function foo() {
console.log(value);
}
function bar() {
value = 2;
foo();
}
bar();//2
因为第二次重新声明的话,bar函数内部的value是个局部变量,只在bar函数内部有效
value= 2 相当于把全局的value值改为2了,foo()执行时内部没有value变量,外部的value就是全局变量value,这时候已经是2了,肯定输出2 了
// 写法 1
function logA() {
console.log(a)
}
// a之前是不能访问到a的
const a = 1
logA() // 1
// 写法2
// 这种是正常写法,但是提升之后跟上面写法一样
const a = 1
function logA() {
console.log(a)
}
logA() // 1
首先,虽然 const a = 1
不会提升,但是 function logA()
是会提升的,所以这两种写法其实是一样的,本质上没有区别。
然后,暂时性死区 TDZ 是对于当前作用域来说的,函数 logA()
创建了自己的函数作用域,而 const a
是在全局作用域的。
JS 的静态作用域,决定了 logA()
的作用域链顺序: logA()
函数作用域 -> 全局作用域。
然后在 logA()
执行时,才会真正按照这个作用域链,从作用域中查找变量。
在执行 logA()
的时候,全局作用域中已经有 const a
,所以没有问题。