js作用域
可以理解为执行环境中变量或函数的作用范围,作用域定义了变量或函数有权访问的其他数据权限,作用域都有一个变量 具体分为以下三种
一、全局作用域
- 全局作用域在页面打开时被创建,页面关闭时被销毁
- 编写在script标签中的变量和函数,作用域为全局,在页面的任意位置可以访问到
- 全局作用域可以认为是window,因为所有的全局变量和函数都是作为window对象的属性和方法创建的
<script>
var a = 1 //全局作用域下变量
var fun = function () {} // 全局作用域下函数
</script>
二、局部(函数)作用域
- 函数调用时,函数作用域被创建,函数执行完毕,函数作用域被销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
- 函数作用域可以访问上层作用域,但是相邻函数作用域之间是相互独立的
function fun () {
var a = 1
console.log(a)
}
fun() // 函数调用时函数作用域被创建,调用完毕函数作用域被销毁
function fun () {
var a = 1
a = a + 1
console(a)
}
fun() // 2
fun() // 2 两次输出均为2,函数每次调用重新创建作用域,相互独立
var b = 1
function fun () {
var a = 1
a = a + b
console.log(a)
}
function fun1() {
console.log(a)
}
fun() // 2,函数可以访问上级作用域b
fun1() // 报错 a 未定义
三、块级作用域(Es6)
Es6之前没有块级作用域,例如
if(true) {
var a = 2
}
console.log(a) // 2
- 在{}(块级作用域)外仍可以访问到块级作用域里的内容 Es6可通过let和const实现块级作用域
<script>
if(true){
let i = 1
}
console.log(i); // 报错 i is not defined
// 同样函数中也会有块级作用域
function fun() {
if(true){
let i = 1
}
console.log(i)
}
fun() // 同样无法输出
</script>
let fun = function() {}console.dir(fun)以上两行代码输出fun对象可以查看到let和const声明的变量是存储在块级作用域中
作用域链
作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。举例说明
var a = 1
function fun() {
var b = a + 1
console.log(b);
}
fun()
从代码执行来看
首先在创建fun函数时,会预先创建一个包含全局变量对象的作用域链,这个作用域链被保存在内部的Scope属性中,当调用fun函数时 ,会为函数创建一个执行环境,然后通过复制函数的Scope属性中的对象构建起执行环境的作用域链,然后创建活动对象AO并推入执行环境的作用域链。在fun执行完毕后,作用域就会被销毁。