二、了解词法作用域
我们需要了解词法作用域的某些方面,看下面的例子:
let val1 = 2
function multiplyThis(n) {
let ret = n * val1
return ret
}
let multiplied = multiplyThis(6)
console.log('example of scope:', multiplied)
在本地执行上下文和全局执行上下文中都有一些变量。JavaScript 的一个复杂之处在于它的变量查找过程。如果它在本地执行上下文中找不到变量,就会在调用上下文中查找。如果没有在调用上下文中找到,最后会在全局执行上下文查找。如果还是没有找到,那它就是 undefined。
1、在全局执行上下文中声明一个新变量 val1,并赋值为 2。
2、第 2-5 行,声明一个新变量 multiplyThis,并将一个函数定义赋给它。
3、第 6 行,在全局执行上下文中声明一个新变量 multiplied。
4、从全局执行上下文内存中获取变量 multiplyThis,并将其作为函数执行。将数值 6 作为参数传递进去。
5、新函数调用就是新的执行上下文。创建一个新的本地执行上下文。
6、在本地执行上下文中,声明变量 n,并赋值为 6。
7、第 3 行,在本地执行上下文中声明变量 ret。
8、第 3 行,用两个操作数执行乘法运算:变量 n 和 val1 的内容。在本地执行上下文中查找变量 n,我们在步骤 6 中声明了它,它的内容是数值 6。在本地执行上下文中查找变量 val1,本地执行上下文中没有标记为 val1 的变量。我们从调用上下文中查找,调用上下文也就是全局执行上下文。让我们在全局执行上下文中查找 val1。是的,它就在那里。它在步骤 1 中定义,值为数值 2。
9、第 3 行,将两个操作数相乘,并将结果指定给变量 ret。6 * 2 = 12。ret 现在是 12。
10、返回 ret 变量,本地执行上下文及其变量 ret 和 n 被销毁。变量 val1 不会被销毁,因为它是全局执行上下文的一部分。
11、回到第 6 行,在调用上下文中将数值 12 分配给变量 multiplied。
12、第 7 行,在控制台中显示变量 multiplied 的值。
所以在这个例子中,我们需要记住一个函数可以访问在其调用上下文中定义的变量,这种现象的正式名称是词法作用域。
