JS学习之——闭包

什么是闭包?

  • 闭包就是 能够读取其他函数内部变量的函数
  • 闭包是指有权访问另一个函数作用域中变量的函数
  • 创建闭包最常见的方式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用域链
  • 闭包的特性
    • 函数内再嵌套函数
    • 内部函数可以引用外层的参数和变量
    • 参数和变量不会被垃圾回收机制回收

说说你对闭包的理解

  • 使用闭包主要是为了设计私有的变量和方法
  • 闭包的优点是可以避免全局变量的污染,
  • 缺点是闭包会常驻内存,会增大内存使用量,使用不当,很容易造成泄漏
  • 在js中,函数即闭包,只有函数才会产生作用域的概念
  • 闭包的另一个用处,是封装对象的私有属性和私有方法
  • 好处:能够实现封装和缓存
  • 坏处:消耗内存、不正当使用造成内存溢出的问题

使用闭包的注意点

  • 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄漏
  • 解决方案是:在退出函数之前,将不使用的局部变量全部删除。

闭包的应用场景

1.setTimeout

原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果。

function f1(a){
	function f2(){
		console.log(a)
	}
	return f2
}
var fun = f1(1)
// 只是赋了一个函数调用给fun,调用f1(1)的时候,返回的是f2里面的打印
setTimeout(fun,1000) //1秒之后打印出1

2.回调

定义行为,然后把它关联到某个用户事件上(点击或按键)。代码通常会作为一个回调(事件触发时调用的函数)绑定到事件上。

<body>
	<div class="box"></div>
	<ul>
	  <li>a1</li>
	  <li>a2</li>
	  <li>a3</li>
	  <li>a4</li>
	</ul>
</body>
<script>
var lis = document.querySelectorAll('ul li')
//将每个 i 的值赋给了 n
for (var i = 0, len = lis.length; i < len; i++){
  (function (n){
    lis[n].onclick = function (){
      console.log(n)//4
    }
  })(i)
}
</script>

3.防抖和节流

什么是防抖和节流??

闭包相关知识

1.作用域

一个名字起作用的范围

var a = 123 // 全局作用域
function fn(){
  var b = 456 // 局部作用域
}
fn()
console.log(a)//123
console.log(b)//报错
  • 局部变量

function fn(){
  var b = 4 //局部变量
  b++
  console.log(b)
}
fn()//5
fn()//5
fn()//5
  • 全局变量

var b = 4 // 全局变量
function fn(){
  b++
  console.log(b)
}
fn()//5
fn()//6
fn()//7

2.一个例子

  • 闭包:直接在内部调用了内部函数,无论调用多少次outer,都是inner的调用
function outer(){
  var a = 1
  function inner(){
    a++
    console.log(a)
  }
  inner()
}
outer()//2
outer()//2
outer()//2

// 在外部访问或操作局部变量
// inner() // 报错
// console.log(a) // 报错
  • 闭包:返回了内部函数,并在外部调用.
  • 在外部操作某个局部变量
function outer(){
  var a = 1
  function inner(){
    a++
    console.log(a)
  }
  return inner
}
var result = outer()
result()//2
result()//3
result()//4

3.词法作用域

静态作用域 :关注点是 函数在何处定义

var a = 123
function fn1(){
  console.log(a)
}
function fn2(){
  var a = 456
  fn1() 
}
fn2()// 123
// 调用fn2的时候执行了 fn1的调用,fn1是在全局定义的。

4.动态作用域

类似 this:关注点是 函数在何处调用

function show(){
  console.log(this)
}
setTimeout(show,1000) //这个是window吧
box.onclick = show //这个this是事件源

5.作用域链

本质上是一个指针列表[变量对象的引用地址,变量对象的引用地址]

  • 变量对象 -> 执行上下文的一部分
  • 执行上下文 -> 执行环境
  • 全局执行环境 - 变量对象 -> window
  • 局部执行环境 - 活动对象 也是 变量对象

6.垃圾回收机制

各大浏览器采用的垃圾回收有两种方法

  1. 标记清除
    当变量进入执行环境时,将这个变量标记为‘进入环境’
    当变量离开执行环境时,将这个变量标记为‘离开环境’,则销毁回收内存。
  2. 引用计数
    跟踪记录每个值被引用的次数,当次数变成0时,则销毁回收内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值