咱们上一部分简单的提到了做用域的概念,在一个函数被解析的时候会在做用域的范围中产生一个环境变量的对象,函数的全部的取值和赋值的操做都在这个环境变量中去操做编程
咱们先定义一个函数里面声明一个变量叫outerValue再在函数的里面再建立一个函数调用该变量
咱们在全局尝试获取到函数里面的变量程序的解析立马会报错
那么咱们先问一个终极的问题,为何要有做用域的区分?你们无论在那个做用域里面随意调用不美滋滋么?其实个人理解是,做用域成功的把js的编程模式编程了“面向对象”的黑盒模式,别人看到你的代码里面封装好的一个函数,只须要管它的入参是什么,它的输出是什么,剩下的关于这个函数是怎么被设计的不用管,拿来用就好,其实现实世界也是这样的,我如今用的笔记本,我只管学会在键盘上码字,不用了解CPU是怎么处理我触发的动做的过程
JS做用域的特色和其余的编程语言大有不同,JS做用域里面没有块级做用域
for循环里面并无造成一个独立的块级做用域,因此咱们在for循环的外面照样能把for循环里面的变量打印出来
JS虽然没有块级做用域,可是咱们能够利用js独特的做用域链的概念用函数模拟块级做用域
可是咱们再新的语法(也不是很新)ES6中产生了块级做用域的限制,ES6产生了let和const两个特殊的声明变量的方式,与var这种声明变量的方式最大的不一样是,var能够变量的声明提高而let和const没有变量的声明提高,等等!!!声明提高又是啥??
注意看这两行代码咱们在第一行的时候调用了在第二行才用var去声明出来的i变量可是咱们代码解析并无报错,而是爆出了undefined!!!!这是由于因为咱们js没有块级做用域的缘由咱们全部的变量声明都会被提到一切程序解析的最前面
也就是咱们其实代码解析的顺序对于浏览器来讲是这个样子滴~,可是自从有了ES6里面的let和const就有了块级做用域,这样的变量提高就没有了
咱们照样用这样的顺序去写代码可是报错了,错误的缘由翻译过来是“没法获取到J,请先初始化”