前言
JavaScript中存在一个Scope的特性,也就是作用域,在学习的过程中不是很好理解,让我们在这浅谈一下作用域。
一、作用域是什么东西?
在百度百科中我们可以查询到,作用域的定义是
作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
换句话说,作用域决定了代码中变量和其它数据的可见性和可访问性,这里我们举一个例子来帮助我们理解
function outSide()
{
var tt="数据1";
}
console.log(tt);//显示:Uncaught ReferenceError: tt is not defined
复制代码
从上述代码中我们可以得知作用域的基本概念,变量tt在全局作用域中未声明,而console.log(tt)这条语句处在全局作用域下,无法得到变量tt的值,所以会报错。作用域决定了变量的生命周期(与函数、块级作用域相关) 任何变量都有生存周期,通俗的理解作用域就是函数的可访问范围,即作用域控制着变量和函数的可见性和生命周期。作用域相当于一个独立的小房间,让房间里的变量不会外泄出去。也就是说,作用域最大的用处就是用于隔离变量,这样同名的变量在不同作用域下就不会产生冲突,因为它们都在自己的小房间里。
二、分别有哪些作用域?
- 全局作用域
- 函数作用域
- 块级作用域
这里我们要知道,JavaScript在ES6之前是没有块级作用域的,从ES6开始,才给我们提供了块级作用域这个概念。
三、这些作用域的作用
- 全局作用域
在全局声明的变量拥有的作用域叫做全局作用域,即这个变量在代码的任何一个地方都能被访问到。那么要如何定义变量,才能让其拥有全局作用域呢,经过查阅,大致有以下几种方式
1. 最外层函数和处在最外层函数之外的变量
var dd="我是在外层函数外定义的变量" function outSide()//外层函数 { var tt="数据1";//函数内的变量,这是内层变量 console.log(tt) } outSide()//数据 console.log(dd)//我是在外层函数外定义的变量 console.log(tt);//Uncaught ReferenceError: tt is not defined 复制代码
从上面的代码可知,外层函数outSide()和在外层变量dd可以在全局当中被访问,而内层变量tt不行,因为内层变量tt位于函数定义域内,无法被访问,访问结果是Uncaught ReferenceError: tt is not defined
2. 没有定义但直接赋值的对象
function outSide()//外层函数 { tt="数据1" var dd="数据2" console.log(dd) } outSide() console.log(tt) 复制代码
在这我们能发现,原本处于函数定义域中的tt能被访问了,因为它此时拥有全局定义域
3. 所有window对象的属性都拥有全局定义域
window的内置属性一般都有全局定义域,例如window.name,window.status等
虽然变量定义在全局定义域中可以在代码的各个地方被访问,但是也有不便利的地方,例如容易产生命名冲突,这在今后与别人合作的工作当中十分不便。
- 函数作用域
函数作用域和全局作用域相反,它是将变量在函数内部进行声明,属于局部作用域,属于这个函数的全部变量可以在整个函数的范围内使用及复用。
- 块级作用域
es6之后,块级作用域可以通过es6新增的let和const命令来进行声明变量,所声明的变量只能在指定的块作用域内被访问,从而达到隔离变量的作用。
块级作用域会在以下情形被创建①一个函数内部②代码块内部({})
注意,部分块语句,不会创造一个新的块级作用域,比如if,switch,for,while等语句,准确的说在其中定义的变量将保存在已经存在的作用域当中
if(true)
{var dd="数据1" } console.log(dd) 复制代码
由结果可知,原本在函数定义域内的变量dd,可在全局中被访问。
let可以将变量的作用域限制在当前的代码块当中,这也是它用来替代var来定义变量原因,它和var的语法一致。
与var生声明的变量相比,let声明的变量不会提升到代码块的顶部,因为在解析代码时,JavaScript引擎也会注意到出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量,在let声明之前的执行瞬间被称为“暂时性死区”(temporal dead zone),在此阶段引用任何后面的才声明的变量都会抛出ReferenceError。所以如果你想要在全局中使用let声明的变量,你要手动将其声明放于顶部。
//name会被提升 console.log(name)//undefined var name="yyds" console.log(age)//ReferenceError:age没有被定义 var age=18 复制代码
以上为个人学习中所得,如有不准确或者疑问的地方可在评论进行讨论与指正,谢谢。