首先要牢记作用域不是存储区域,存储区域称作内存,作用域的作用就如家人之间不能叫错辈分一样,辈分的称呼是有一套法则的,而作用域就是变量们的查找和读取法则,更形象点的可以把作用域比作一套 c ++(chrome v8) 算法,作用域的理解有助于帮我们知道一些 javascript 中很神奇的现象如提升、闭包。
在我们打开网页的后,作用域始终发挥着作用,词法分析会根据作用域对变量进行声明以确定变量在作用域下的嵌套关系,下面是一个简单的例子。
var a = 2;
首先浏览器获取到包含这段脚本的代码,然后解析 html、解析这段脚本,进行到词法分析会把这句代码拆开 var a; a = 2; 然后就会声明 a = undefined, 变量提升就是那么来的,此时代码还没执行,甚至还不知道语义,因为这里只是进行了词法分析。以下是一个包含嵌套规则的例子。
function foo(a) {
var b = a * 2;
function bar(c) {console.log(a, b, c); // 2 4 12
}
bar(b * 3);
}
foo(2);
浏览器引擎会在作用域规则下为这些变量画圈,或者是在存储时标注了某种规则,圈或者规则就包含了变量在作用域下的嵌套规则。
知道了什么是作用域,那么来说一下作用域下的一个重要成员 - 闭包,他俩啥关系呢,正是由于作用域中的嵌套规则才形成了闭包,那闭包究竟是什么阿,大部分人会这样说“通过闭包可以在函数外部能访问到函数内部的变量”,首先阿这不是对闭包的功能性进行了描述吗,下面阐述个人对于闭包概念的理解,从数学角度来看闭包是一个集合,这个集合包含集合内和集合边界上的点,当我们在一个函数内创建另一个函数时就产生了闭包,从理论来讲是这样的,这个闭包包含当前的函数的词法环境和上级函数的语法环境,至于“通过闭包可以在函数外部能访问到函数内部的变量”的形成不单单是因为闭包,还多亏了 javascript 的垃圾回收机制,导致闭包还在访问所以没有被回收。