词法作用域
在编程语言中,作用域存在两种工作模式,一种是动态作用域,一种是词法作用域(静态作用域)。在JavaScript使用的就是词法作用域。
什么是词法作用域
词法作用域,顾名思义,就是定义在词法阶段的作用域。用通俗一点的话讲,就是函数的作用域在函数定义的时候就已经决定了。
函数作用域原理(个人理解,有错误欢迎各位大佬斧正)
每一个JavaScript函数都是Function对象的一个实例,在Function对象中有一个仅供JavaScript引擎存取的内部属性[[ scope]],翻译成中文为 作用域。当一个函数创建时它的[[ scope]]属性就已经被对象填充完成了,这个被对象填充完成的集合就叫作用域链。
JavaScript引擎读取变量时,会从作用域链自上而下的寻找,找到第一个就不再往下找了,顺序从活动对象至全局对象。如果未找到就会undefined。
关于作用域、作用域链、活动对象更详细内容可以阅读:数据存取之作用域链
一个简单的例子
预测一下结果? Tom?Angus?Mike?
var name = "Angus";
function showName() {
let name = "Mike";
console.log(name);
}
function tom() {
let name = "Tom";
showName();
}
tom();
结果是 Mike ,这个结果的原因我上面也解释过了,在showName函数创建时,它的作用域链就已经创建好了,而JavaScript使用的是词法作用域,这就意味着,即使你在tom函数中调用showName函数,但showName作用域链中name依旧是"Mike",就算你将name=“Mike"注释掉,结果也不会是"Tom”,而是"Angus"。
总结
无论函数在哪里被调用,也无论它如何被调用,它的词法作用域都只由函数被声明时所处的位置决定,这就是JavaScript的词法作用域。