表妹又来问JavaScript的闭包啦,这就给你把来龙去脉讲清楚
什么是闭包
闭包是指有权访问另一个函数作用域中的变量的函数。
函数中的name,test1不会被垃圾回收机制回收,直到页面关闭
function myName() {
let test1 = 1
let test2 = 2
let name = 'agul'
let foo = {
getName: function () {
return name
},
setName: function (value) {
name = value
console.log(test1)
}
}
return foo
}
let bar = myName()
bar.setName('pjh')
console.log(bar.getName())
1. 闭包形成的原理
- 作用域链,当前作用域可以访问上级作用域中的变量
- 全局变量只用页面关闭才会销毁
2. 闭包解决的问题
- 函数作用域中的变量在函数执行结束就会销毁,但是有时候我们并不希望变量销毁
- 在函数外部可以访问函数内部的变量
3 闭包带来的问题
-
容易造成内存泄露
-
内存泄漏:占用的内存没有及时释放,内存泄露积累多了就容易导致内存溢出
-
闭包
function fn1() { var a = 4 function fn2() { console.log(++a) } return fn2 } var f = fn1() f()
-
-
4 闭包的应用
for (var i = 0; i < 5; i++) {
(function (j) {
setTimeout(() => {
console.log(j)
}, j * 1000)
})(i)
}
//相当于
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i)
}, i * 1000)
}
两个按钮,分别记录点击次数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button>test1</button>
<button>test2</button>
<script> function count() {
var num = 0 return function () {
return ++num } } var fn1 = count() var fn2 = count() document.querySelectorAll('button')[0].onclick = function () {
console.log(fn1()) } document.querySelectorAll('button')[1].onclick = function () {
console.log(fn2()) } </script>
</body>
</html>
传入一个参数返回一个函数,返回的函数又能够传入参数使用。
function curryingCheck(reg) {
return function (txt) {
return reg.test(txt)
}
}
var isEmail = curryingCheck(/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/)
console.log(isEmail('wyn@nowcoder.com')) // false
上方代码是传入验证邮箱的正则调用函数,向返回函数中传入验证的值就能够进行验证真假了。验证其他也是可以如此使用~