js高级程序设计官方解释
闭包是指有权访问另一个函数作用域中的变量的函数。
原理
闭包保存了外部函数的作用域链中的变量对象
闭包与变量和this的关系
闭包能够保存外部函数的变量,实现块级作用域
function printNum() {
for (var i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i)
}, 100)
}
}
printNum() // 10,10,...,10
function printNumClosure() {
for (var i = 0; i < 10; i++) {
(function (j) {
setTimeout(() => {
console.log(j)
}, 100)
})(i)
}
}
printNumClosure() // 0,1,...,9
function printNumEs6() {
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i)
}, 100)
}
}
printNumEs6() // 0,1,...,9
复制代码
把外部作用域的this对象保存在闭包能够访问的变量中,就可以让闭包访问该对象
var name = 'the window'
var obj = {
name: 'my obj',
getNameFunc: function() {
return function() {
return this.name
}
}
}
console.log(obj.getNameFunc()()) // the window
var name = 'the window'
var obj = {
name: 'my obj',
getNameFunc: function() {
var that = this
return function() {
return that.name
}
}
}
console.log(obj.getNameFunc()()) // my obj
复制代码
闭包的作用
模仿块级作用域、实现私有变量和静态私有变量
使用立即实行函数实现块级作用域
function outputNum() {
(function() {
for (var i = 0; i < 10; i++) {
alert(i)
}
})()
alert(i) // 报错,访问不到i
}
复制代码
实现私有变量:
function myObj() {
// 私有变量和私有函数,外部访问不到
var privateVal = 10
function privateFun() {
return false
}
// 特权方法
this.publicMethod = function() {
privateVal++
return privateFun()
}
}
复制代码
静态私有变量:
(function() {
var name = ''
Person = function(value) {
name = value
}
Person.prototype.getName = function() {
return name
}
Person.prototype.setName = function(value) {
name = value
}
})()
var person1 = new Person('brady')
console.log(person1.getName()) // brady
person1.setName('mia')
console.log(person1.getName()) // mia
var person2 = new Person('Michael')
console.log(person1.getName()) // Michael
console.log(person2.getName()) // Michael
复制代码
在私有作用域中定义的私有变量或函数,会被所有实例共享(name被闭包保存了)
闭包引发的问题
内存泄漏:通常函数的作用域及其所有变量都会在函数执行结束后被销毁,但是当函数返回一个闭包时,函数的作用域将会一直在内存中保存到闭包不存在为止
可以令该变量=null来主动销毁它