js闭包是一个拥有许多变量和绑定了这些变量的环境的表达式。
闭包的特点:
1、作为一个函数变量的一个引用,当函数返回时,其处于激活状态,一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
2、js闭包允许使用内部函数,这些内部函数可以访问它们所在的外部函数中声明的参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
扩展资料:
js闭包实例:
1、函数内部可以直接读取全局变量
<script type="text/javascript">
var n=100
function parent(){
alert(n)
}
2、读取函数内的局部变量
parent()//100
</script>
function parent(){
m=50
}
parent()
alert(m)//50
参考资料来源:百度百科:javascript闭包
写这个文章也是为了回顾下闭包的只是点,其实许多前端对闭包都有点一知半解,包括我自己也是。
闭包函数:声明在一个函数中的函数,叫做闭包函数。
闭包:内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。其实闭包在我看来就是变量作用域的。
let c = test()其实就是将test函数运行的结果赋值给c,其返回的是d方法
执行后的结果是30,因为正常来说a和b其实是局部变量,只作用于test函数。而c()的运行环境并没有变量a和b,其实这就是b包。由于在javascript中,只有函数内部的子函数才能读取局部变量,所以说,闭包可以简单理解成“定义在一个函数内部的函数“。
所以,在本质上, 闭包是将函数内部和函数外部连接起来的桥梁 。
1、是前面提到的 可以读取函数内部的变量
2、是 让这些变量的值始终保持在内存中 ,不会在调用后被自动清除。
闭包的注意事项:
1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。 解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
在网上看到了一道练习题,跟this指向也有关系,可以看下
var name = "The Window"
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name
}
}
}
alert(object.getNameFunc()())
回调函数概念: 函数的参数callback是另一个参数,这个参数在原始数据中执行
例如:
let arr = [11, 22, 33, 44, 55, 66, 77, 88, 99]
function liFor(arr, callback) {
for (let i = 0i <arr.lengthi++) {
if (callback(arr[i])) {
console.log(arr[i])
}
}
}
console.log('---------遍历数组----------')
liFor(arr, val =>true)
console.log('---------输出奇数----------')
liFor(arr, val =>val % 2 !== 0)
console.log('---------输出被3整除----------')
liFor(arr, val =>val % 3 === 0)
console.log('---------输出被3和6整除----------')
liFor(arr, val =>val % 3 === 0 &&val % 6 === 0)
闭包函数概念:定义一个a方法,在a方法中定义一个b方法,并且b方法里面用到了a方法里面定义的变量,那么此时就形成了闭包函数,由于内部方法里面,用到外部方法里面的变量,外部方法里面的那个变量会一直在内存中存保存着。两个方法嵌套定义,里面的方法,用到了外面方法里面定义的变量,此时这两个方法就形成了闭包。
例如:
function a() {
console.log('a函数被调用了...')
let num1 = 100
let num2 = 200
function b() {
console.log('b函数被调用了...')
console.log(num1 + num2)
}
//返回的返回值也是一个函数,那么a函数就是高阶函数。
return b
}
// 通常情况下,函数执行完成后,函数里面定义的变量,会被销毁。
// a函数,已经调用完毕了,但是a函数里面定义变量,始终在内存中,因为b函数中用到了a函数中定义的变量。
// 那么此时这两个函数,就称之为:闭包函数。
let c = a()
c()
console.log('------------------------------------------')
// 闭包函数的实际案例
function calc(num1, num2, type) {
switch (type) {
case '+':
console.log(`${num1}+${num2}=${num1 + num2}`)
break
case '-':
console.log(`${num1}-${num2}=${num1 - num2}`)
break
}
}
// 在实际开发中,我们在做num1和num2的计算之前,可能需要先做其他事情
let num1 = 100
let num2 = 50
// 在做其他事情的过程中,我们的数据很有可能会被篡改。
console.log('查看用户是否登录')
num1 = 555
num2 = 145
console.log('检查用户的权限')
calc(num1, num2, '+') //运行结果不对,因为变量的值被篡改了。
console.log('------------------------------------------')
// 定义一个闭包函数,实现计算器功能
function myCalc(num1, num2, type) {
switch (type) {
case '+':
return function() {
return num1 + num2
}
case '-':
return function() {
return num1 - num2
}
}
}
//先准备好你的数据
let n1 = 100
let n2 = 50
//将你的数据传给计算器方法,由计算器方法,返回一个计算方法。
let js = myCalc(n1, n2, '+')
//在做具体的计算之前,还先做些其他的事情
console.log('查看用户是否登录')
n1 = 555
n2 = 145
console.log('检查用户的权限')
//其他事件准备好了后,执行计算方法
console.log(js())