js——闭包相关知识

1.闭包是什么?

  • 闭包是一个具有作用域代码块
{}
{var a=20}
if(){};
for(){};
label1:{}
//都不是闭包 虽然是封闭的 但没有作用域

  有作用域的函数:

function fn(){
	var a=20;
	console.log(a) //打印局部变量a的值  20
}
fn();
console.log(a) //不能访问函数内部的局部变量  全局作用域中没有定义 所以报错 

2.闭包的使用场景?

1)函数内部的变量外部是无法访问的 但可以通过返回一个闭包来访问

  • 外部操作闭包来间接访问函数内部的变量,闭包可以决定这个变量的操作方式
  • 利用了函数的作用域和运行时的作用域

  案例1 

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

2)利用函数每次调用时生成的独立调用栈

  •  利用函数的形参保存临时变量的值

  引例

var arr = []
for (var i = 0; i <5; i++) {
     var obj = {}
     arr.push(obj)    //循环五次 生成五个空对象放入数组arr中
}
console.log(arr)     //[{},{},{},{},{}]
for (var i = 0; i <= arr.length; i++) {
     arr[i].age = i
     arr[i].tool = function () {
     console.log(i)  //5 
     } 
}
console.log(arr[2].age) //2
arr[3].tool() //for循环没有作用域 先执行完for循环再打印 即循环的最末值5
              //每次放入的都是同一个i 

 案例

function  tool (index) {			//内部的形参变量是各自独立的	
	arr[index]=function fn(){
					console.log(index)
				}
}
var arr=[]
for(var i=0;i<5;i++){			
	tool(i)           //函数每次调用传入的是不同的值 
}
arr[2]()//2   

 优化

var arr=[]
for(var i=0;i<5;i++){			
	(function(index){
	   arr[index]=function fn(){
					  console.log(index)
			      }
	})(i)    //每次for循环让函数调用  
}            //函数调用过程中生成一个作用域内部有个形参变量index  index就是保存的临时变量i的值
arr[2]()  //2

3)利用函数的独立作用域 生成业务代码块 内部的变量相互不冲突不污染全局变量

  • 用函数将代码块包起来 : (function(){})(); 一定要加分号

4)回调函数 利用函数复用的功能,制作复用工具,参数返回值

//执行业务 5000 行数据
//生成了一个数据 "hello"
function fn(arg1) {
    var data = "hello"
    arg1(data)
}
fn(function (a) {
    console.log(a)
})

5)可以把一个闭包封装到原型中 这样每一个对象都可以共用闭包工具

3.闭包的优缺点

优点:

1.函数内部的变量想被外部使用 但是语法决定不能使用 可以利用闭包解决

2.一些临时数据 如循环的i的值 希望(延时)业务中使用  可使用闭包把临时数据保存到局部作用域中

3.防止变量污染 可以用闭包把业务变量放在局部作用域中

缺点:导致内存泄漏 

  内存泄漏:

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

  解决方案:

  1. 尽量避免使用闭包
  2. 在可能存在泄漏的地方把标识符引用为null

  内存管理机制:垃圾回收机制  引用计数  ==>是底层浏览器的代码实现的功能

    1.垃圾回收机制:系统定期查看代码的执行情况 观察创建的对象使用的可能性 若不再使用就释放内存

    2.引用计数:每一个对象都有引用者,如果引用者为0就释放内存              

function fn() {
       var obj = {
              age: 20
       }
       function tool() {
            return obj.age
       }
       return tool //使用闭包
}
var re = fn() //fn函数调用完毕 内部的obj对象没有释放  会导致内存泄漏
console.log(re())

//解决方案:尽量不使用 或 在可能存在泄漏的地方把标识符引用为null
function fn() {
       var obj = {
              age: 20
       }
       function tool() {
            return obj.age
       }
       return tool //使用闭包
}
var re = fn()
re = null; 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈ha~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值