JavaScript高级__深入了解闭包
理解闭包
1.如何产生闭包
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
2.闭包到底是什么
闭包是嵌套的内部函数
包含被引用变量(函数)的对象
注意:闭包存在于嵌套的内部函数中
3.产生闭包的条件
函数嵌套
内部函数引用了外部函数的数据(变量/函数)
function fn1() {
// 此时闭包就已经产生了(函数提升,内部函数对象已经创建了)
var a =2
function fn2() {
a++
console.log(a)
}
return fn2
}
var f = fn1()
f() // 3
f() // 4
f = null // 闭包死亡(包含闭包的函数对象成为垃圾对象)
常见的闭包
1.将函数作为另一个函数的返回值
2.将函数作为实参传递给另一个函数调用
闭包的作用
1.延长局部变量的生命周期
2.从外部可以(间接)操作函数内部的局部变量
闭包的生命周期
1.产生:在嵌套内部函数定义执行完成就产生了(不是在调用时)
2.死亡:在嵌套内部函数成为垃圾对象时
闭包的应用
自定义JS模块
*具有特定功能得js文件
*将所有的数据和功能都封装在一个函数内部(私有的)
*只向外暴露一个包含n个方法的对象或函数
*模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能
案例一
function myModule() {
// 私有变量
var msg = 'Hello World'
// 操作私有变量的函数
function upperCase() {
console.log('upperCase()' + msg.toUpperCase())
}
function lowerCase() {
console.log('lowerCase()' + msg.toLowerCase())
}
// 向外部暴露对象(给外部使用的方法)
return {
upperCase: upperCase,
lowerCase: lowerCase
}
}
案例二
(function () {
// 私有变量
var msg = 'Hello World'
// 操作私有变量的函数
function upperCase() {
console.log('upperCase()' + msg.toUpperCase())
}
function lowerCase() {
console.log('lowerCase()' + msg.toLowerCase())
}
// 直接挂在window上
window.myModule = {
upperCase: upperCase,
lowerCase: lowerCase
}
})()
闭包的缺点以及解决
1.缺点
*函数执行完后,函数内的局部变量没有释放,占用内存时间变长
*容易造成内存泄漏
2.解决
*能不用闭包就不用
*及时释放 (赋值null)
闭包代码案例
代码一
var name = "window"
var obj = {
name : 'object',
getName : function() {
return function() {
return this.name;
}
}
}
console.log(obj.getName()()) // window
代码二
var name = "window"
var obj = {
name : 'object',
getName : function() {
var that = this
return function() {
return that.name
}
}
}
console.log(obj.getName()()) // object
代码三
function fun(n, o) {
console.log(o)
return {
fun: function(m) {
return fun(m, n)
}
}
}
var aa = fun(0); // undefined
aa.fun(1); // 0
aa.fun(2); // 0
aa.fun(3); // 0
var bb = fun(0).fun(1).fun(2).fun(3); // undefined 0 1 2
var cc = fun(0).fun(1); // undefined 0
cc.fun(2); // 1
cc.fun(3); // 1
内存溢出与内存泄漏
1.内存溢出
*一种程序运行出现的错误
*当程序运行需要的内存超过了剩余的内存时,就抛出内存溢出的错误
2.内存泄漏
*占用的内存没有及时释放
*内存泄漏积累多了就容易导致内存溢出
*常见的内存泄漏
i意外的全局变量
ii没有及时清理的计时器或回调函数
iii闭包

浙公网安备 33010602011771号