JavaScript学习笔记(七)——闭包是什么?

闭包是什么?(面试题)

以下是回答:

1.闭包描述:

官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

具有作用域的代码块就是闭包。不一定是函数。

面试题:闭包是什么?
答:闭包是可访问上一层函数作用域里变量的函数,即便上一层函数已经关闭。
2.闭包技术的好处:

常见几种场景:

场景一:一个函数返回函数内部的工具函数,外部通过工具函数间接访问函数局部变量的过程 (利用了函数的作用域和运行时作用域)

 function alipay() {
			 	 money=1000				
			 }
			 alipay()
			 console.log(money)
						
			 function alipay() {
			 	 var money=1000
			 	 //不能让函数之外的代码直接操作money  但是可以让自己的内部工具操作 然后返回这个工具
			 	 function  tool () {
			 	 	money-=20
			 	 }
			 	return  tool
			 }
						
			 function  meituan () {
			 	// var m=alipay()
			 	// m=m-20
			 	// console.log(m)
			 	var aplitool=alipay()
			 	aplitool()
			 }
			 meituan()

场景二:利用函数子调用,每次调用内部的局部变量或者形参都是独立的,来保存一些临时变量(利用了函数每次调用时生成的独立调用栈(每次调用时,重新在内存中生成一个对象))

var arr = []
        for (var i = 0; i < 5; i++) {
            var obj = {}
            arr.push(obj)
        }
        console.log(arr)

        for (var i = 0; i < arr.length; i++) {
            arr[i].age = i
            arr[i].tool = function () {
                console.log(i)//2
            } 
        }
        console.log(arr[2].age)
        arr[3].tool() // 5

场景三:利用函数的独立作用域,来生成业务代码块,内部的变量相互不冲突污染全局变量。

var a='重庆真美';
var b=52;
function fn(){
b=b+1;
}
fn();
function look(){
    console.log(b);
}
look();
fn();
fn();
console.log(a);
look();

//张三n行代码之后   又来了个人李四写代码直接引用张三的代码张三.js  
//可能引起变量污染 改了别人的代码
//解决:一个js文件一个闭包 --> 自调用函数包起来
(Function ()){
    
}();
//这里;必须加上不能省略

**场景四:**可以把一个闭包封装到原型中,这样每一个对象都可以共用闭包工具;

场景五:回调函数,最特殊的闭包,利用函数复用的功能,制作复用工具,有形参和返回值。

见后文回调函数案例 ~

3.项目的看法

闭包优点

  1. 函数内部的变量想要被外部程序使用,但是语法决定了外部不能使用,可以利用闭包解决;
  2. 一些临时数据,比如for循环的i的值,希望延时业务中使用,可以使用闭包把临时数据保存到局部作用域中;
  3. 防止变量污染,可以用闭包把一些业务变量放在局部作用域中……

闭包缺点

虽然闭包好用,可以解决很多问题,但是它使用不当的话,就会有一些致命问题:内存泄漏。

内存管理机制:垃圾回收机制,引用计数机制,这些技术是底层浏览器代码实现的功能;

​ 系统定期查看js的执行情况,观察创建的对象有没有可能被使用,如果没可能,就释放内存,每一个对象都有被(至少一个“人”)引用,如果没有(0个)被引用就释放。

全局环境下的变量不会被回收。

内存泄漏:指的是浏览器在运行网页时,会执行js代码,引用数据会在内存中占用内存空间,如果有一个对象创建了,而且占用了内存,却没有业务使用(想用都用不了),这就叫内存泄漏。

闭包导致的内存泄漏

例子:
function fn(){
	var obj={age:20};
    function tool(){
		return obj.age;
    }
    return tool;
}
var re=fn();//调用完毕  内部的obj对象没有释放,占用内存
// 闭包可能回引用obj对象,所以不会释放

解决方案:

  • 尽量避开使用闭包(推荐)
  • 在可能存在泄漏的地方把标识符引用为null(麻烦,每一次还要判断是否有可能被使用)
function fn(){
	var obj={age:20};
    function tool(){
		return obj.age;
    }
    return tool;
}
var re=fn();
re=null;//解决
4.真实的在项目中使用闭包的场景

根据自己做的项目中案例,自己进行描述……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值