JavaScript深入之词法作用域和动态作用域

  1. var a = 10;
  2. var o = {
  3. a:11,
  4. b:{
  5. fn:function(){
  6. console.log(a);
  7. }
  8. }
  9. }
  10. 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 ,所以没有问题。