前言
闭包在 JavaScript 编程中是一个基本知识点,必须掌握的,下面就由本文简单讲解一下什么是闭包。
一、闭包概念
(1)当一个函数内部定义了另一个函数,并且这个内部函数引用了外部函数的变量时,就会形成一个闭包。这个内部函数可以访问外部函数的变量,即使外部函数已经执行完毕并返回了,这些变量仍然存在于内存中,因为内部函数保留了对它们的引用。
(2)闭包可以用来创建私有变量和方法,以及实现模块化和函数式编程等高级技术。但是,如果不注意使用闭包,可能会导致内存泄漏和性能问题。
/* ---- ---- ---- ---- ^ 闭包示例 ---- ---- ---- ---- */
/**
* 银行卡账户
*/
const account = () => {
// 余额
let balance = 10 // 10
// 存钱与取钱事件句柄方法
const handleEventMethod = (event, number) => {
if (event === 'save') {
balance += number
} else if (event === 'draw') {
balance -= number
}
return balance
}
return handleEventMethod
}
// 交易
const deal = account()
console.log(deal)
// 存钱
const saveMoney = deal('save', 1500)
console.log('存钱后 =>', saveMoney) // 1510
// 取钱
const drawMoney = deal('draw', 1000)
console.log('取钱后 =>', drawMoney) // 510
// 查询余额
const money = deal('view')
console.log('余额 =>', money) // 510
/* ---- ---- ---- ---- / 闭包示例 ---- ---- ---- ---- */
二、let和闭包的关系
在JavaScript中,let关键字用于声明块级作用域的变量,而闭包是指函数可以访问其外部作用域中的变量。因此,let和闭包之间有一定的关系。当使用let声明变量时,该变量只在当前块级作用域中可见,而不会污染全局作用域。这意味着,如果在函数内部使用let声明变量,该变量只能在该函数内部访问,而不能在函数外部访问。然而,如果在函数内部使用闭包,函数可以访问其外部作用域中的变量,包括使用let声明的变量。这是因为闭包可以捕获其外部作用域中的变量,并在函数内部使用它们。
例如,以下代码演示了如何使用let和闭包:
function createCounter() {
let count = 0;
return fn() {
count++;
console.log(count);
}
}
const counter = createCounter();
counter(); // 输出1
counter(); // 输出2
counter(); // 输出3
在这个例子中,createCounter函数返回一个闭包,该闭包可以访问其外部作用域中的count变量。每次调用counter函数时,闭包都会更新count变量的值,并将其输出到控制台上。由于count变量是使用let声明的,它只在createCounter函数内部可见,而不会污染全局作用域。
三、let和var的区别
相同点:let和var都是用来声明变量的关键字
异同点:
(1)作用域:var声明的变量是函数作用域或全局作用域,而let声明的变量是块级作用域。块级作用域指的是在花括号{}内部定义的变量只在该花括号内部有效。
(2)变量提升:var声明的变量会进行变量提升,即在声明之前就可以使用该变量,但其值为undefined。而let声明的变量不会进行变量提升,即在声明之前使用该变量会报错。
(3)重复声明:在同一作用域内,使用var声明同名变量不会报错,但会覆盖之前的值。而使用let声明同名变量会报错。
(4)循环中的使用:在for循环中使用var声明的变量会存在变量共享的问题,而使用let声明的变量则不会。
总结:let声明的变量更加安全可靠,因为它避免了变量提升和变量共享的问题,并且可以更好地控制变量的作用域。
四、如何理解 var 变量提升?
在 JavaScript 中,变量提升是指在代码执行之前,JavaScript 引擎会将变量的声明提升到作用域的顶部,这个过程被称为变量提升。
在使用 var 声明变量时,变量提升会将变量的声明提升到当前作用域的顶部,但是变量的赋值不会被提升。这意味着,即使在变量声明之前使用变量,JavaScript 引擎也不会报错,而是会返回 undefined。
例如:
console.log(a); // undefined
var a = 1;
上面的代码中,变量 a 的声明被提升到了作用域的顶部,但是变量 a 的赋值并没有被提升,所以在第一行代码中,变量 a 的值为 undefined。需要注意的是,变量提升只会将变量的声明提升到当前作用域的顶部,而不是全局作用域的顶部。如果在函数内部使用 var 声明变量,那么变量的作用域就是当前函数的作用域,而不是全局作用域。