一、JavaScript中的作用域
作用域是当前的执行上下文,值和表达式在其中“可见”或可被访问。如果一个变量或表达式不在当前的作用域中,那么它是不可用的。
代码语言:javascript复制function foo() {
var x = 'sfa'
}
console.log(x) // x is not defined
全局作用域和函数作用域
全局作用域:在JavaScript中 {} 外面的作用域就是全局作用域,里面的变量和函数等其他资源可以在任意地方被访问到。一般来说以下几种情况拥有全局作用域
- 最外层函数和在最外层函数外面定义的变量
// 该函数和该变量供全局使用,foo函数内部依旧能够使用foo函数(此处未演示)
var a = 23;
function foo() {
var b = 1;
function inner() { // 内部函数不能被全局使用
return false
}
}
console.log(a, foo) // 23 [Function: foo]
console.log(b) // b is not defined
// console.log(inner) // inner is not defined
- 不使用var声明直接赋值的变量
因为JavaScript在执行是会自动隐式地创建该全局变量
代码语言:javascript复制// 相当于在全局:var b;
function foo() {
b = 1;
}
foo()
console.log(b) // 1
- 全局对象(globalThis)
全局对象可以通过globalThis获取,浏览器环境中指 Window
代码语言:javascript复制console.log(globalThis) // Node 环境中
Object [global] {
global: [Circular *1],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
},
queueMicrotask: [Function: queueMicrotask],
performance: Performance {
nodeTiming: PerformanceNodeTiming {
name: 'node',
entryType: 'node',
startTime: 0,
duration: 43.25670003890991,
nodeStart: 0.508400022983551,
v8Start: 1.6218000054359436,
bootstrapComplete: 33.73820000886917,
environment: 12.502800047397614,
loopStart: -1,
loopExit: -1,
idleTime: 0
},
timeOrigin: 1683861064321.689
},
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate] {
[Symbol(nodejs.util.promisify.custom)]: [Getter]
}
}
函数作用域:在函数内部定义的变量、函数和其他资源。在这个作用域内声明的变量,就只能在它这个作用域和其子作用域中才能使用。
块级作用域
ES6新增的块级作用域:用let和const声明的变量才存在块级作用域,在该代码块外部访问不到该变量。在{ }中用let和const声明的变量就是一个块级作用域。
代码语言:javascript复制{
let a = 1;
console.log(a) // 1
}
console.log(a) // a is not defined 外部访问不到
二、作用域链
作用域链指的是各个作用域的嵌套关系和查找机制。
代码语言:javascript复制function foo() {
var b = 'foo中的b'
function bar() {
// 当前作用域中没有声明b则查找上一级作用域(创建该作用域的那个域),依次类推,直至到全局作用域
return b
}
return bar()
}
console.log(foo()) // foo中的b
上面代码中的b就是一个自由变量,即在当前作用域中没有定义b
三、js中的执行上下文
执行上下文(简称上下文)我们可以理解成一个js代码执行的环境,在代码执行阶段被创建,里面包含了定义的所有变量、函数以及this指向等。每个上下文都有一个关联的变量对象,保存着上面说的那些数据。虽然无法通过代码访问,但是后台处理数据会用到它。
全局上下文是最外层的上下文,表示全局上下文的对象可能不一样,在浏览器中就是 window 对象;上下文在其所有代码都执行完毕后会销毁(全局上下文在应用程序退出前被销毁)。
上下文中的代码在执行的时候会创建变量对象的一个作用域链(scope chain)。
希望本篇文章能够帮助到大家!