深入浅出地学习 JavaScript 作用域和闭包。本入门指南将通过简单示例讲解全局、局部和块级作用域,以及闭包的工作原理。
介绍
学习 JavaScript 时,你会遇到两个最重要的概念:作用域和闭包。这两个概念乍一听可能有点令人困惑,但它们构成了 JavaScript 底层工作原理的基础。如果没有对作用域和闭包的深入理解,编写干净、无 bug 的代码就会变得更加困难。
在本指南中,我们将逐步分解内容,以便您清楚地理解。
您将学到什么
阅读完本文后,您将:
了解 JavaScript 中范围的含义。
了解全局作用域、局部作用域和块作用域之间的区别。
了解闭包是什么以及它为何重要。
查看简单示例,了解范围和闭包在实际代码中如何工作。
获得在自己的项目中使用这些概念的信心。
JavaScript 中的作用域是什么?
作用域是代码中可以访问变量的区域。可以将作用域视为一组规则,用于决定在何处以及如何使用变量。
JavaScript 中有三种主要的作用域类型:
全局范围: 在任何函数或块之外声明的变量可以在代码中的任何位置访问。
let name = "Wisdom"; // global variable
function sayName() {
console.log(name); // accessible here
}
sayName(); // Output: Wisdom局部(函数)范围:在函数内部声明的变量仅在该函数内部可用。
function greet() {
let message = "Hello!";
console.log(message); // works here
}
greet();
console.log(message); // Error: message is not defined块作用域:通过 let 和 const 引入,块作用域将变量限制在声明它们的块 {} 内。
if (true) {
let age = 30;
console.log(age); // works inside block
}
console.log(age); // Error: age is not definedJavaScript 中的闭包是什么?
当函数记住其外部作用域中的变量时,即使该作用域已经运行完毕,也会发生闭包。
简单来说,闭包允许内部函数“记住”并使用在其外部定义的变量。
例子:
function outer() {
let count = 0;
function inner() {
count++;
return count;
}
return inner;
}
let counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3事情是这样的:
该outer函数创建一个变量count。
该inner函数使用该变量。
即使outer完成后,inner仍然可以访问count。这就是闭包的作用。
为什么闭包有用?
闭包非常强大,因为它:
保护数据:闭包内的变量不能从外部直接访问。
帮助构建私有函数:有助于编写安全代码。
支持高级模式:例如回调、事件处理程序和函数式编程。
保护数据的示例:
function createBankAccount() {
let balance = 100;
return {
deposit(amount) {
balance += amount;
return balance;
},
withdraw(amount) {
balance -= amount;
return balance;
},
getBalance() {
return balance;
}
};
}
let account = createBankAccount();
console.log(account.deposit(50)); // 150
console.log(account.withdraw(20)); // 130
console.log(account.getBalance()); // 130这里的余额是私有的。它不能直接从外部更改,只能通过提供的函数更改。
结论
理解JavaScript 中的作用域和闭包对于编写更好的代码至关重要。作用域告诉你变量可以在何处使用,而闭包允许函数在其外部函数运行结束后仍能访问变量。
作为初学者,如果一开始觉得比较棘手,不必担心。通过一些小例子练习,你很快就会明白这些概念的强大之处。一旦你掌握了作用域和闭包,你就能为构建更高级的 JavaScript 应用程序打下更坚实的基础。