作用域常见面试题

67 阅读2分钟

image.png

  1. 全局作用域(GO)初始化

    • 变量 n 被声明并赋值为 100
    • 函数 foo 被声明,其内部代码为 n = 200
    javascript
    GO: { n: 100, foo: 函数对象 }
    
  2. 调用 foo() 时的作用域链

    • 执行 foo() 时,进入函数作用域,创建活动对象(AO)。
    • 函数内部试图访问变量 n。由于函数作用域内未声明 n,​沿着作用域链向全局作用域查找
    javascript
    AO(函数 foo 的活动对象): 无局部变量 n
    
  3. 修改全局变量 n

    • 在全局作用域中找到 n,将全局 n 的值从 100 修改为 200
    javascript
    GO: { n: 200, foo: 函数对象 }  // 全局 n 被修改
    
  4. 最终输出结果

    • console.log(n) 访问全局作用域的 n,输出修改后的值 200

image.png

  1. 全局作用域(GO)初始化

    • 变量 n 被声明并赋值为 100
    • 函数 foo 被声明,其内部代码包含变量提升逻辑。
    javascript
    GO: { n: 100, foo: 函数对象 }
    
  2. 调用 foo() 时的执行上下文

    • 变量提升阶段
      函数内部声明 var n = 200 的变量 n 被提升至函数顶部,初始值为 undefined

      javascript
      AO(函数 foo 的活动对象): { n: undefined }
      
    • 代码执行阶段

      1. 第一个 console.log(n)
        当前作用域(AO)中存在 n,值为 undefined,输出 undefined

      2. 执行 n = 200
        修改 AO 中的 n 为 200

        javascript
        AO: { n: 200 }
        
      3. 第二个 console.log(n)
        从 AO 中读取 n,输出 200

  3. 函数执行完毕后的全局输出

    • console.log(n) 访问全局作用域(GO)的 n,值仍为 100

image.png

  1. 全局作用域(GO)初始化

    • 变量 a 被声明并赋值为 100
    • 函数 foo 被声明,其内部代码包含变量提升逻辑。
    javascript
    GO: { a: 100, foo: 函数对象 }
    
  2. 调用 foo() 时的执行上下文

    • 变量提升阶段
      函数内部 var a = 100 的声明被提升至函数顶部,初始值为 undefined

      javascript
      AO(函数 foo 的活动对象): { a: undefined }
      
    • 代码执行阶段

      1. 执行 console.log(a)
        当前作用域(AO)中存在 a,值为 undefined,因此输出 undefined
      2. 函数提前返回
        由于图示中存在 return 语句,后续的 var a = 100 的赋值操作未执行,AO 中的 a 保持 undefined
  3. 全局输出 console.log(a)

    • 访问全局作用域(GO)中的 a,值仍为 100

补充:在js引擎里边,如果变量没有被声明,会被放到全局对象里边