1.词法作用域
词法作用域就是指作用域是由代码中函数声明的位置来决定的,所以词法作用域是静态作用域,通过它能预测代码在执行过程中如何查找标识符。
function bar() {
var myName = "极客世界"
let test1 = 100
if (1) {
let myName = "Chrome浏览器"
console.log(test)
}
}
function foo() {
var myName = "极客邦"
let test = 2
{
let test = 3
bar()
}
}
var myName = "极客时间"
let myAge = 10
let test = 1
foo() // 1
bar函数声明在全局作用域中,其test往上找就是全局变量test = 1。
2.作用域链
function bar() {
console.log(myName)
}
function foo() {
var myName = "极客邦"
bar()
}
var myName = "极客时间"
foo() // 极客时间
每个执行上下文的环境变量中,都包含了一个外部引用,用来指向外部的指向上下文,我们把这个指向上下文称为outer
3.闭包
function foo() {
var myName = "极客时间"
let test1 = 1
const test2 = 2
var innerBar = {
getName:function(){
console.log(test1)
return myName
},
setName:function(newName){
myName = newName
}
}
return innerBar
}
var bar = foo()
bar.setName("极客邦")
bar.getName()
console.log(bar.getName())
// 1
// 1
// 极客邦
指向到return 的调用栈
foo 函数执行完的调用栈
根据词法作用域,内部函数getName和setName总是可以访问他们的外部函数foo中的变量,当innerBar对象返回给全局变量bar时,即使foo函数已经执行结束,但是getName和setName函数依然可以使用foo函数中的变量myName和test1,这两个变量依然保存在内存中。
闭包定义
根据词法作用域的规则,内部函数总是可以访问其他外部函数中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数以及执行结束,但是我们函数内部引用外部函数的变量依然保存在内存中,我们把这些变量的集合称为闭包。