作用域(作用域)转自掘金,得到作者认同1.作用域是什么概念:作用域是一个变量,函数和对象的可访问性。从使用的角度来说,scope就是变量的使用范围,即代码中哪些部分可以访问该变量,哪些部分不能访问该变量,换句话说就是该变量在程序的哪些区域是可见的.代码演示:functionFun(){varinVariable="internalvariable";}Fun();console.log(inVariable);//UncaughtReferenceError:inVariableisnotdefined//inVariable是在Fun函数内部定义的,属于局部变量,外部无法访问,所以会报错。从存储的角度看,作用域本质上是一个对象,作用域中的变量可以理解为对象的成员总结:作用域是代码的执行环境,全局角色域是全局执行环境,localscope是函数的执行环境,都是栈内存2.作用域分类作用域分为全局作用域和局部作用域。在ES6之前,局部作用域只包括函数作用域。ES6的到来为我们提供了“块级范围”(由一对花括号包裹),可以通过添加命令let和const来实现;而对于全局作用域,这里有一个小细节需要注意:在网络浏览器中,全局作用域被认为是window对象,所以所有的全局变量和函数都是作为window对象的属性和方法创建的。在Node环境中,全局作用域是全局对象。全局范围很容易理解。现在让我们解释一下本地范围。我们先来看看函数作用域。所谓函数作用域,顾名思义,就是函数定义产生的作用域。代码示例:functionfun1(){varvariable='abc'}functionfun2(){varvariable='cba'}fun1();fun2();//这里有两个函数,每个函数都有一个变量与同名。在严格模式下,程序不会报错,//这是因为同名的两个变量位于不同的函数中,也就是不同的作用域,所以不会冲突。让我们再看看块级作用域。在ES6之前,JavaScript没有块级作用域,只有全局作用域和函数(局部)作用域。块语句({}中间的语句),如if和switch条件语句,for和while循环语句,与函数不同,它们不会创建新的作用域;但是ES6及之后的版本,块语句也会创建一个新的作用域,块级作用域可以通过新的命令let和const来声明,声明的变量在指定块的作用域之外是无法访问的。当let声明的语法与函数内代码块(由一对大括号括起来)中的var语法匹配时,将创建块级作用域。基本上可以用let代替var来声明变量,但是变量的作用域会被限制在当前代码块内(注意:块级作用域不影响var声明的变量)。但是使用let有几点需要注意:声明变量不会提升到代码块的顶部,即没有变量提升,禁止在()内重复声明同一个变量for循环语句,即括号内会建立一个隐藏作用域,这个作用域不属于for后面的{},只有for后面的{}产生的块作用域才能访问这个隐藏作用域,使得循环中的boundblockscope有神奇的效果。这里分别演示一下ES5和ES6版本代码,ES5:if(true){vara=1}for(vari=0;i<10;i++){...}console.log(a)//1console.log(i)//10ES6:for(leti=0;i<10;i++){console.log(i);//0,1,2,3,4,5,6,7,8,9}控制台。log(i);//UncaughtReferenceError:iisnotdefinedif(true){leti=9;}console.log(i);//UncaughtReferenceError:iisnotdefinedscopechain概念:多个组成的链结构对范围对象的连续引用。使用说明:在Javascript中使用一个变量时,Javascript引擎会先尝试在当前作用域中寻找该变量,如果没有找到,再在上层作用域中寻找,以此类推,直到找到该变量或者已经到达全球范围。如果在全局范围内仍然没有找到该变量,则直接报错。存储解释:作用域链在JS内部以数组的形式存储。数组的第一个索引对应函数本身的执行上下文,即当前执行代码所在环境的变量对象,下一个索引对应的空间存放对象的外部执行环境,以及依此类推,直到全局执行环境代码示例:vara=100functionfun(){varb=200console.log(a)//100//funfunctionlocal作用域内没有变量a,找找从它的上层,也就是全局作用域来看,//A在全局作用域被赋值100,所以输出100console.log(b)//200fun函数在本地起作用有一个变量b在domain,赋值200,输出200}fun()再举个栗子:vara=10functionfun(){console.log(a)}functionshow(f){vara=20(function(){f()//10,不是20;函数的作用域在函数定义的时候就确定了,和函数在哪里调用无关})()}show(fun)由于变量查找是沿着作用域链实现的,所以作用域链又称为变量查找机制。容易理解吗?让我在这里添加一点范围。范围最重要的一点是安全性。只能在特定区域访问变量。外部环境不能访问内部环境中的任何变量和函数,即可以向上查找,但不能向下查找。有了作用域,我们就可以避免在程序的其他地方意外访问到其他变量和函数。修改变量会导致程序崩溃。范围减轻了命名事物的压力。我们可以在不同的作用域中定义相同的变量名,这些变量名不会冲突。
