2-29-闭包
作者:互联网
day29
闭包
闭包是什么
- 1.官方解释:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。(函数就是一个表达式)
- 2.通俗的来说:JavaScript中所有的function都是一个闭包。不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”。
- 3.什么是闭包:闭包是指在函数外部能够访问函数作用域中变量(局部变量)的函数;
或者说闭包就是能够读取其他函数内部(局部变量)变量的函数;
或者说闭包是指有权访问另一个函数作用域中的变量(局部变量)的函数;
由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数 - 4.闭包就是在函数体内部return另外的一个函数体,并且将外层函数利用IIFE的写法直接将其调用并讲内层函数的引用返回给一个变量。
- 5.闭包就是在外层函数里嵌套一个内层函数,内层函数作为外层函数return数据的返回值。外层函数是自调用函数,并且将自身的返回值(也就是内层函数本身)赋值给一个变量。
在JS执行环境下文中调用该变量就等价于调用了内层函数,并且在内层函数中可以访问到外层函数的局部变量又并且外层函数的局部变量不会被多次声明,此时就形成了一种闭包的写法。
闭包解决的问题/作用/使用场景(优点)
- 可以将全局变量变为一个局部变量,减少全局作用域的污染。
- 外层函数中的局部变量 被修改的唯一途径就是调用内层函数,除此之外无法进行修改或是获取。
- 让这些变量(外部函数的局部变量)的值始终保持在内存中。
闭包的缺点
- 坏处:这个变量不会被js的垃圾回收机制自动清除,会一直驻留在内存中,既闭包会破坏掉JS的垃圾回收机制清除闭包内局部变量的行为,所以有内存泄漏(爆内存)的危险。
闭包的代码ji适用情况
直观的标准代码
//普通代码
var a = 5;
function fn() {
a++;w
return a;
}
console.log(fn())//6
console.log(fn())//7
console.log(fn())//8
console.log(fn())//9
//闭包代码
let add = (function() {
var a = 5;
return function() {
a++;
return a;
}
})()
console.log(add())//6
console.log(add())//7
console.log(add())//8
console.log(add())//9
闭包的基本代码
function fn1() {
var n = 100;
// 下面这句话是定义函数,而不是调用
let fn2 = function() {
console.log("fn2", n);
}
return fn2; //把fn2返回出去。
}
//1
// let f = fn1();
//f(); //----- fn2 100
//2
fn1()();
//1=2
闭包中修改局部变量-1
function fn1(){
var n = 100; //在内存中申请空间,名字n,值是100;
// 下面这段代码是定义函数,不是调用
let fn2 = function(){ //在内存中申请空间,名字fn2,值是函数
n++;
console.log("fn2",n);
}
return fn2;
}
let f = fn1();
f();//101
f();//102
f();//103
闭包中修改局部变量-2
function fn1(){
var n = 100; //在内存中申请空间,名字n,值是100;
// 下面这段代码是定义函数,不是调用
let fn2 = function(){ //在内存中申请空间,名字fn2,值是函数
n++;
console.log("fn2",n);
}
return fn2;
}
fn1()(); //101
fn1()(); //101
两个子函数
function fn1(){
var n = 100; //在内存中申请空间,名字n,值是100;
// 下面这段代码是定义函数,不是调用
let fn2 = function(){ //在内存中申请空间,名字fn2,值是函数
n++;
console.log("fn2",n);
}
let fn3 = function(){ //在内存中申请空间,名字fn2,值是函数
n++;
console.log("fn2",n);
}
return [fn2,fn3];
}
let arr = fn1();
arr[0]();//fn2
arr[1]();//fn3
闭包示例-01
function test1(){
var arr = [];
for(var i=0; i<5; i++){
//赋值;(定义函数)
arr[i] = function(){
return i;
}
}
console.log("i",i);
return arr;
}
var arr = test1();
// console.log(arr[0]);
console.log(arr[0]());
console.log(arr[1]());
console.log(arr[2]());
闭包示例-02
function test1(){
var arr = [];
for(var i=0; i<5; i++){
//赋值;(定义函数)
arr[i] = function(){
return i;
}() //定义并调用
}
console.log("i",i);
return arr;
}
var arr = test1();
console.log(arr);
// arr[0]
用循环的方式给dom元素绑定事件
//示例:用循环的方式给html元素的事件赋值时,没法把循环变量作为函数的参数进行处理
// window.onload:当前窗口里的文档加载完毕之后,调用函数
window.onload = function(){
let inputs = document.getElementsByTagName("input"); //inputs 是nodeList类型(dom节点的集合)
for(var i=0;i<inputs.length;i++){
// inputs[i].index = i;//给dom元素增加一个自定义属性
inputs[i].setAttribute("index",i);
inputs[i].onclick = function(){
// console.log(i);//4
console.log(this.getAttribute("index"));
}
}
}
九九乘法表
function outerFunc(){
for(var i=1;i<=9;i++){
(function(maxCount){
for(var j=1;j<=maxCount;j++){
document.write(j+"*"+maxCount+"="+maxCount*j+" ")
}
})(i);
document.write("<br>");
}
}
outerFunc();
用闭包的方式实现 mult(5)(6)(7),表示三个数的乘法(567)
// 用闭包的方式实现 mult(5)(6)(7),表示三个数的乘法(5*6*7)
// // 一、 mult(5)(6) 《==》 5*6
// function mult(m){
// return function(n){
// return m*n
// }
// }
// 二、
// 用闭包的方式实现 mult(5)(6)(7),表示三个数的乘法(5*6*7)
function mult(m) {
return function(n) {
return function(k) {
return m * n * k
}
}
}
console.log(mult(5)(6)(7));
对某些数据的修改,只想限定在某个函数里,而不是任何地方都可以修改
// 对某些数据的修改,只想限定在某个函数里,而不是任何地方都可以修改
function fn1(){
let count = 10;
function add(){
count++;
}
return add;
}
let f = fn1();
f();
f();
标签:闭包,function,console,log,29,fn2,函数 来源: https://blog.csdn.net/HXX548888/article/details/112851331