一、c/c++,js的作用域
c/c++都有块级作用域,因为之前学习c的时候就是按照一种从上往下的思维去理解函数,也并没有去深入思考过,但是在接触js后遇到的一个相对困难的问题就是作用域问题。在了解之后才知道原来他们的作用域不同,js中只有函数作用域。而且不同的地方挺多。所以就稍微了解了一下,如果有不对的地方,欢迎大家评论区指正我
二、块级作用域
在es5之前没有块级作用域,只有函数作用域,函数作用域有两个特点
1.变量泄露
作为循环的计数变量,在执行完函数后泄露为全局变量
2.内层变量覆盖外层变量
这个应该是最值得注意的地方。
例如,如果是块级作用域,那么执行顺序应该是,先进行了变量scope的定义与赋值,此时他应该是一个全局变量,因此在函数t()中,他的值应该还是global直到第二次赋值。
但是实际在函数作用域中的结果是,第一个输出是undefined,第二个输出是local。并没有出现预想的global,这应该就是因为内层变量提升导致覆盖了外层变量。所以其实原代码可以扩展为
即在执行内层函数的过程中出现了再一次的函数定义,并将原值覆盖。导致scope成为了undefined。
三、let
在es6中,出现了let,而let可以有效地避免变量提升。是不是就可以理解为,当我使用let变量时,可以当作习惯性的c/c++的读程序方式去操作呢。(!!!错误观点!!!)
2021.9.17 今天用java语言的int和let做了一个对比,
得出了不同的结论
如果按照之前我的想法
那么这两种应该执行结果是相同的,但是事实不是这样
java得出的输出是正常的1和2(部分代码省略0 0)
而在使用let时,得出了意料之外的结果,报错!
于是又再次陷入迷惑,不过也有了解决迷惑的过程。再次搜资料后发现
- var的创建和初始化被提升,赋值不会被提升。
- let的创建被提升,初始化和赋值不会被提升。
- function的创建、初始化和赋值均会被提升。
这就是他们会出现区别的原因吧,嘿嘿!
今天在尝试的时候发现了新的问题,
当出现这样的问题后,发现并没有出现变量提升(输出为1),后来经过尝试和查询相关资料发现,原来是自己把自己搞迷糊了,变量提升出现的条件是,在函数体中再次出现了相同变量的赋值,因为使用var定义变量时,会在编译器编译前进行一个定义操作,
例如原代码出现变量提升时应该是这样
此时出现了变量提升,因为var会做一个预定义操作,因此此代码又等同于
。
如有不对,希望大神指正,编程小白,希望大家多多包涵