美文网首页
let、const定义的变量为什么通过window获取不到

let、const定义的变量为什么通过window获取不到

作者: 一蓑烟雨任平生_cui | 来源:发表于2019-04-16 17:20 被阅读0次

    let、const定义的变量为什么通过window获取不到

    先看几个case:

    let count = 10
    
    console.log(count)
    console.log(window.count)
    

    输出:10 undefined

    const length = 5
    const obj = {
      length: 6,
      foo(bar) {
        bar()
        arguments[0]()
      }
    }
    
    function bar() {
      console.log(this.length)
    }
    
    obj.foo(bar, 2, 4)
    

    输出: 0 3

    var length = 5
    const obj = {
      length: 3,
      foo(bar) {
        bar()
        arguments[0]()
      }
    }
    
    function bar() {
      console.log(this.length)
    }
    
    obj.foo(bar, 3)
    

    输出: 5 2

    为什么?ES5 和 ES6变量声明方式的区别导致的。首先总结下ES5 和 ES6 的变量声明方式。

    1. ES5 变量声明方式就两种 var、function
    2. ES6 有 let、const、import、class,再加上ES5 的var 和 function 总共6种
    3. DOM 的顶层对象是document,BOM的顶层对象是window,Node的全局对象是global
    4. ES5中顶层对象的属性等价于全局变量
    5. 在ES6中,用let、const、import、class定义的全局变量并没有作为全局对象的属性,所以通过window获取时,如果window存在和变量同名的属性,则获取的是window中该属性的原始值,否则为undefined
    6. 用let const在声明的时候,是创建了一个遮蔽window同名属性的全局变量,debuger一下就可以看出来用 let const 定义的变量作用域为Script对象中,和Window/Global同级。

    如图:

    Markdown

    所以

    1. case1首先打印10,其次是window中不存在的count属性,undefined
    2. case2 调用bar时,this指向window,而window中的length属性为0,所以输出0。通过arguments[0]调用,函数内的this指向argument,arguments为类数组,其length属性为实参的个数,即 3
    3. case3 使用var声明length,会修改window中的length属性(window的length 属性的原始值是当前窗口中frames的数量(包括IFRAMES)),所以值为0

    暂时性死区(TDZ)

    let const声明的变量会放在TDZ中,TDZ指的是从变量的当前的作用域开始到变量的声明之间的区域,这一段区域的变量是无法读写的。只有在执行了声明之后,才从TDZ移除。

    注意点:

    变量提升控制的是当前作用域或者执行环境,因此某个TDZ也只负责某个执行环境。

    console.log(typeof value)  // undefined
    
    {
      console.log(typeof value) // 报错 value is not defined
      const value = 'rose'
    }
    

    可以看出if外访问 value 不会报错,因为 if 外 typeof value时变量还没有在TDZ中,所以是undefined。

    相关文章

      网友评论

          本文标题:let、const定义的变量为什么通过window获取不到

          本文链接:https://www.haomeiwen.com/subject/stqiwqtx.html