-
Notifications
You must be signed in to change notification settings - Fork 3.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
第 27 题:关于 const 和 let 声明的变量不在 window 上 #30
Comments
js的这种"绝对领域"(作用域)是通过什么创造的呢?是通过”{ }“这两个符号创造的,有代码为证: let a = 1;
{
let aa = 20;
console.log(aa); // 20
}
console.log(a); //
console.log(aa); // Uncaught ReferenceError: aa is not defined
|
在ES5中,全局变量直接挂载到全局对象的属性上,所以能在window上看到var声明的变量 |
你这个相当于 是块作用域了,没有在全局作用域中 |
与之相比var let const三种,前者因为var的变量会提升到window,但是let个const不会,let ,const会生成块作用域,同一作用域下let和const不能声明同名变量,而var可以 |
我同时还想补充一点的就是如果在声明之前调用let const 声明的变量的时候会报错(这里面有一个暂时性死区的问题)不能再声明之前调用 console.log(a); //Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 1; |
const和let会生成块级作用域,可以理解为
ES5没有块级作用域的概念,只有函数作用域,可以近似理解成这样。 |
scope作用域链 |
关于这道题题解,发现答案没有从根本上解释全局环境下声明的let和const 为什么没有挂在window对象 上面??? 其实关于这道题我们需要了解全局环境与全局执行上下文的相关概念后,才能解释为什么是这样 GlobalEnv是一个复合环境,包括一个由global构成的对象环境(objEnv)和一个一般声明的环境(declsEnv)组合而成,它是双环境组成的,统一交付一个环境存取的界面(objEnv/declsEnv 对应 Global/Script) let/const 声明会放在declsEnv里面,而var的变量会通过ObjEnv来声明, 所以显而易见说明,let,const 声明的变量不在window对象 其实这里还有很多内容可以展开讨论
关于环境概念也可参考的的笔记 关于答案更权威解释和更多可以展开内容的讨论 参考极客时间 |
同意 XiaoDHuang 的解答。 另外,最高赞答案说“全局环境下通过 let 和 const 声明变量处于script块级作用域中“,这句话概念上肯定是不正确的。没有理解 TC39 成员是如何在向后兼容 ES5 的情况下引入块级作用域的。 那么如何在 global 环境中获取? |
在定义变量的块级作用域中就能获取 |
class、let定义的即便是全局对象,但不是顶层对象的属性,在window自然获取不到,只能去定义变量的块级作用域里获取 |
var的创建和初始化被提升,赋值不会被提升; |
我开始以为这个let和const以及var不难,当我真正去尝试深入的时候发现涉及到一个全新的概念:script作用域。我理解他是我认为他和window是同级的作用域,他们共存的,但是一直有一个东西困扰我就是,这个script作用域是怎么来的?是在script脚本开始执行时就和window一样被创建了?可当我没有写任何代码就debugger的时候,我发现他并不存在,只有全局window的存在。当我尝试使用const和let时,他们便被创建出来了!同时我又去验证了一件事情,我在一个块作用域下去创建一个变量,如果我使用var,那么这个变量依然在全局,但是当我使用const或let时,他会创建一个全新的块作用域,并将这些变量放到这个块作用域下。所以我总结了一下:
debugger
var a = 'window a'
debugger
const b = 'script b'
debugger
{
const c = 'Block c'
debugger
}
function Fun() {
const a = 'Fun a'
var b = 'Fun b'
debugger
}
Fun() 感兴趣的可以自行去浏览器控制台的源代码那块点作用域去测试。 |
let const class 不会挂到全局作用域,而是在 script 作用域 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let |
因为let和const没有变量提升呀 |
|
在ES5中,顶层对象的属性和全局变量是等价的,var 命令和 function 命令声明的全局变量,自然也是顶层对象。
但ES6规定,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性,但 let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。
在哪里?怎么获取?通过在设置断点,看看浏览器是怎么处理的:
通过上图也可以看到,在全局作用域中,用 let 和 const 声明的全局变量并没有在全局对象中,只是一个块级作用域(Script)中
怎么获取?在定义变量的块级作用域中就能获取啊,既然不属于顶层对象,那就不加 window(global)呗。
The text was updated successfully, but these errors were encountered: