Javascript 閉包
1.理解闭包
1.1 如何产生闭包?
当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时,就产生了闭包
1.2 闭包到底是什么?
i:闭包是嵌套的内部函数
ii:包含被引用变量(函数)的对象
iii:闭包存在于嵌套的内部函数中
1.3 产生闭包的条件:
i:嵌套的函数
ii:内部函数引用了外部函数的数据(变量/函数)
function foo(){
var a = 1;
function bar(){
//内部函数bar引用了外部函数foo的a变量,此时产生闭包
console.log(a);
}
bar()
}
foo();2.常见的闭包
2.1 将函数作为另一个函数的返回值
function fn1(){
var a = 1;
function fn2(){
a++;
console.log(a);
}
return fn2
}
var fn = fn1();//产生闭包,变量a = 1
fn() //2
fn() //32.2 将函数作为实参传递给另一个函数调用
function delay(msg, time){
setTimeout(function(){
alert(msg)
}, time)
}
delay('Hello Closure', 1000)3.闭包的作用
3.1 使用函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
3.2 让函数外部可以操作(读/写)到函数内部的数据(变量/函数)
4.闭包的生命周期
4.1 产生:在嵌套的内部函数定义执行完成时就产生了(不是在调用)
4.2 死亡:在嵌套的内部函数成为垃圾对象时
function foo(){
//此时闭包已经产生(函数提升,内部函数已经创建)
var a = 1;
function bar(){
console.log(a);
}
return bar;
}
var f = foo();
f()
f = null //闭包死亡(包含闭包的函数成为垃圾对象)5.闭包的使用:自定义JS模块
(function (window){
//私有数据
var msg = "Hello closure";
function doSomething() {
console.log("doSomething() "+msg.toUpperCase());
}
function doOtherthing() {
console.log("doOtherthing() "+msg.toLowerCase());
}
//向外暴露对象
window.module = {
doSomething:doSomething,
doOtherthing:doOtherthing
}
})(window)module.doSomething(); //doSomething() HELLO CLOSURE module.doOtherthing(); //doOtherthing() hello closure
6.闭包的缺点及解决
6.1 缺点:
i:函数执行完后,函数内的局部变量没有释放,占用内存时间会变长
ii:容易造成内存泄漏
6.2 解决:
i:能不用闭包就不用
ii:及时释放
function fn1() {
var ary = new Array(100000);
function fn2() {
console.log(ary)
}
return fn2;
}
var fn = fn1()
fn()
fn = null; //让内部函数成为垃圾对象-->回收闭包补充知识点:
1.内存溢出
i:一种程序运行出现的错误
ii:当程序运行需要的内存超过了剩余内存时,就抛出内存溢出的错误
2.内存泄漏
i:占用的内存没有及时释放
ii:内存泄漏积累多了,容易导致内存溢出
iii:常见的内存泄漏:意外的全局变量,没有及时清理的定时器或者回调函数,闭包
//内存溢出
var obj = {};
for(var i = 0; i < 10000; i++){
obj[i] = new Array(1000000)
}
//浏览器报错:显示此网页时内存不足//内存泄漏
//意外的全局变量
function fn() {
ary = new Array(100000)
console.log(ary)
}
fn()
//没有及时清理的定时器或者回调函数
var intervalId = setInterval(function() {
console.log("hello closure")
}, 1000)
clearInterval(intervalId) //清除定时器
//闭包
function fn1() {
var ary = new Array(100000);
function fn2() {
console.log(ary)
}
return fn2;
}
var fn = fn1()
fn()面试题1
//code1
var name = "outside"
var obj = {
name:"inside",
getNameFunc:function(){
return function(){
return this.name
}
}
}
alert(obj.getNameFunc()()) //? 是否有闭包?
//code2
var name = "outside"
var obj = {
name:"inside",
getNameFunc:function(){
var that = this;
return function(){
return that.name
}
}
}
alert(obj.getNameFunc()()) //? 是否有闭包面试题2
function foo(v1, v2){
console.log(v2);
return {
foo:function(v3){
return foo(v3, v1);
}
}
}
var a = foo(0); a.foo(1); a.foo(2); a.foo(3) //?
var b = foo(0).foo(1).foo(2).foo(3)//?
var c = foo(0).foo(1); c.foo(2); c.foo(3)//?PS:面试题答案参考评论区
共同學習,寫下你的評論
評論加載中...
作者其他優質文章