js闭包的简单理解
小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
我们可能经常时候闭包,只是你未发现这是闭包而已罢了。
理解闭包只需要学会三个基本的事实。
第一个事实:JavaScript允许你引用在当前函数以外定义的变量。
function sayHi() {
let Hi = "Hi"
function name(name) {
return Hi + "," + name
}
return name("罗老师")
}
let result = sayHi()
console.log(result) // Hi,罗老师
第二个事实:即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。
如果这听起来让人难以置信,请记住,JavaScript的函数是第一类(first-class对象)。这意味着,你可以返回一个内部函数,并在稍后调用它。
function sayHi() {
let Hi = "Hi"
function name(name) {
return Hi + "," + name
}
return name
}
let result = sayHi()
let a = result("a老师")
let b = result("b老师")
console.log(a) // Hi,罗老师
console.log(b) // Hi,罗老师
和第一个例子不同的是,不是在外部调用函数 sayHi 中立即调用 name("罗老师"),而是返回 name 函数本身。因此变量 a 的值是内部的 name 函数,调用变量 a 实际上是调用了 name 函数。但即使 sayHi 函数已经返回,name 函数仍然能记住 Hi 变量的值
学习闭包的第三个也是最后一个事实 : 闭包可以更新外部变量的值。
实际上,闭包存储的是外部变量的引用,而不是它们的值的副本。因此,对于任何具有访问这些外部变量的闭包,都可以进行更新。一个简单的惯用法 box 对象说明了这一切。它存储了一个可读写的内部值。
function box() {
let value = undefined;
return {
set:function(newValue){value=newValue},
get:function(){return value},
type:function(){return typeof value}
}
}
let result = box();
console.log(result.type()) //undefined
console.log(result.get()) //undefined
result.set(100)
console.log(result.get()) // 100
console.log(result.type()) // number
这个例子产生了一个包含三个闭包的对象。这三个闭包是set、get 和 type 属性。它们都共享访问 value 变量。set 闭包更新 value 的值,随后调用 get 和 type 查看更新的结果。
总结
- Javascript 允许你引用当前函数以外定义的变量
- 即使外部函数已经返回,当前函数仍可以引用在外部函数所定义的变量
- 闭包可以更新外部变量的值。实际上,闭包存储的是外部变量的引用,而不是它们的值的副本