4、闭包
5、内存溢出与内存泄露
内存溢出
一种程序运行出现的错误 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
内存泄露
占用的内存没有及时释放 内存泄露积累多了就容易导致内存溢出 常见的内存泄露:
详细讲解
闭包前置知识
< ! --
需求 : 点击某个按钮, 提示"点击的是第n个按钮"
-- >
< script type= "text/javascript" >
var btns = document. getElementsByTagName ( 'button' )
for ( var i= 0 , length= btns. length; i< length; i++ ) {
( function ( i ) {
var btn = btns[ i]
btn. onclick = function ( ) {
alert ( '第' + ( i+ 1 ) + '个' )
}
} ) ( i)
}
< / script>
理解闭包
< ! --
1. 如何产生闭包?
* 当一个嵌套的内部 ( 子) 函数引用了嵌套的外部 ( 父) 函数的变量 ( 函数) 时, 就产生了闭包
2. 闭包到底是什么?
* 使用chrome调试查看
* 理解一: 闭包是嵌套的内部函数 ( 绝大部分人)
* 理解二: 包含被引用变量 ( 函数) 的对象 ( 极少数人)
* 注意: 闭包存在于嵌套的内部函数中
3. 产生闭包的条件?
* 函数嵌套
* 内部函数引用了外部函数的数据 ( 变量/ 函数)
-- >
< script type= "text/javascript" >
function fn1 ( ) {
var a = 3
function fn2 ( ) {
console. log ( a)
}
}
fn1 ( )
< / script>
常见的闭包
< ! --
1. 将函数作为另一个函数的返回值
2. 将函数作为实参传递给另一个函数调用
-- >
< script type= "text/javascript" >
function fn1 ( ) {
var a = 2
function fn2 ( ) {
a++
console. log ( a)
}
return fn2
}
var f = fn1 ( )
f ( )
f ( )
function showMsgDelay ( msg, time ) {
setTimeout ( function ( ) {
console. log ( msg)
} , time)
}
showMsgDelay ( 'hello' , 1000 )
< / script>
闭包的作用
< ! --
1. 使用函数内部的变量在函数执行完后, 仍然存活在内存中 ( 延长了局部变量的生命周期)
2. 让函数外部可以操作 ( 读写) 到函数内部的数据 ( 变量/ 函数)
问题 :
1. 函数执行完后, 函数内部声明的局部变量是否还存在?
2. 在函数外部能直接访问函数内部的局部变量吗?
-- >
< script type= "text/javascript" >
function fun1 ( ) {
var a = 3 ;
function fun2 ( ) {
a++ ;
console. log ( a) ;
}
return fun2;
}
var f = fun1 ( ) ;
f ( ) ;
f ( ) ;
< / script>
闭包的生命周期
< ! --
1. 产生 : 在嵌套内部函数定义执行完时就产生了 ( 不是在调用)
2. 死亡 : 在嵌套的内部函数成为垃圾对象时
-- >
< script type= "text/javascript" >
function fun1 ( ) {
var a = 3 ;
function fun2 ( ) {
a++ ;
console. log ( a) ;
}
return fun2;
}
var f = fun1 ( ) ;
f ( ) ;
f ( ) ;
f = null
< / script>
闭包的应用_自定义JS模块
< ! --
闭包的应用2 : 定义JS 模块
* 具有特定功能的js文件
* 将所有的数据和功能都封装在一个函数内部 ( 私有的)
* 只向外暴露一个包信n个方法的对象或函数
* 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能
-- >
< script type= "text/javascript" src= "05_coolModule.js" > < / script>
< script type= "text/javascript" >
var module = coolModule ( )
module. doSomething ( )
module. doOtherthing ( )
< / script>
function coolModule ( ) {
var msg = 'atguigu'
var names = [ 'I' , 'Love' , 'you' ]
function doSomething ( ) {
console. log ( msg. toUpperCase ( ) )
}
function doOtherthing ( ) {
console. log ( names. join ( ' ' ) )
}
return {
doSomething : doSomething,
doOtherthing : doOtherthing
}
}
闭包的缺点及解决
< ! --
1. 缺点
* 函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长
* 容易造成内存泄露
2. 解决
* 能不用闭包就不用
* 及时释放
-- >
< script type= "text/javascript" >
function fn1 ( ) {
var a = 2 ;
function fn2 ( ) {
a++ ;
console. log ( a) ;
}
return fn2;
}
var f = fn1 ( ) ;
f ( ) ;
f ( ) ;
f = null
< / script>
闭包面试题
var name = "The Window" ;
var object = {
name : "My Object" ,
getNameFunc : function ( ) {
return function ( ) {
return this . name;
} ;
}
} ;
console. log ( object. getNameFunc ( ) ( ) ) ;
var name2 = "The Window" ;
var object2 = {
name2 : "My Object" ,
getNameFunc : function ( ) {
var that = this ;
return function ( ) {
return that. name2;
} ;
}
} ;
console. log ( object2. getNameFunc ( ) ( ) ) ;
< script type= "text/javascript" >
function fun ( n, o ) {
console. log ( o)
return {
fun : function ( m ) {
return fun ( m, n)
}
}
}
var a = fun ( 0 )
a. fun ( 1 )
a. fun ( 2 )
a. fun ( 3 )
var b = fun ( 0 ) . fun ( 1 ) . fun ( 2 ) . fun ( 3 )
var c = fun ( 0 ) . fun ( 1 )
c. fun ( 2 )
c. fun ( 3 )
< / script>
内存溢出与内存泄露
< ! --
1. 内存溢出
* 一种程序运行出现的错误
* 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误
2. 内存泄露
* 占用的内存没有及时释放
* 内存泄露积累多了就容易导致内存溢出
* 常见的内存泄露:
* 意外的全局变量
* 没有及时清理的计时器或回调函数
* 闭包
-- >
< script type= "text/javascript" >
function fn ( ) {
a = [ ]
}
fn ( )
setInterval ( function ( ) {
console. log ( '----' )
} , 1000 )
< / script>