JavaScript 中的函数作用域是指变量和函数的可访问性范围。作用域决定了代码块中的变量和其他资源的可见性。JavaScript 的作用域主要有两种类型:全局作用域和局部作用域。
在函数外部声明的变量或函数具有全局作用域,这意味着它们可以在代码的任何地方被访问。
var globalVar = "I am global";
function showGlobalVar() {
console.log(globalVar); // 输出: "I am global"
}
showGlobalVar();
在函数内部声明的变量或函数具有局部作用域,它们只能在声明它们的函数内部被访问。
function showLocalVar() {
var localVar = "I am local";
console.log(localVar); // 输出: "I am local"
}
showLocalVar();
console.log(localVar); // 报错: localVar is not defined
ES6 引入了 let
和 const
关键字,它们允许创建块级作用域。块级作用域是由一对花括号 {}
定义的代码块。
{
let blockVar = "I am block-scoped";
console.log(blockVar); // 输出: "I am block-scoped"
}
console.log(blockVar); // 报错: blockVar is not defined
当访问一个变量时,JavaScript 引擎首先在当前作用域查找该变量。如果在当前作用域找不到,它会向上级作用域查找,直到找到全局作用域。这个查找过程形成了作用域链。
var globalVar = "global";
function outer() {
var outerVar = "outer";
function inner() {
var innerVar = "inner";
console.log(innerVar); // 输出: "inner"
console.log(outerVar); // 输出: "outer"
console.log(globalVar); // 输出: "global"
}
inner();
}
outer();
闭包是指一个函数能够记住并访问它的词法作用域,即使这个函数在其词法作用域之外执行。
function outer() {
var outerVar = "I am from outer function";
return function inner() {
console.log(outerVar); // 输出: "I am from outer function"
};
}
var innerFunc = outer();
innerFunc(); // 即使 outer 函数已经执行完毕,inner 函数仍然可以访问 outerVar
问题:意外的全局变量导致命名冲突。
解决方法:使用 let
和 const
替代 var
来声明变量,避免全局污染;使用模块化编程,如 ES6 模块或 CommonJS。
问题:闭包导致的内存泄漏。
解决方法:确保不再需要的闭包及时解除引用,特别是在使用事件监听器时。
通过理解作用域的概念和规则,可以更好地编写可维护和避免错误的 JavaScript 代码。
领取专属 10元无门槛券
手把手带您无忧上云