看前两章即可
https://www.cnblogs.com/xiangqianjin/p/6595115.html
一、闭包用来访问内部变量
但是对于对象来说,直接return this.xxx也可以访问
var name = 'The Window'; var obj = { name:'My Object', getName:function(){ return this.name; } } console.log(obj.getName());
如果直接return name,没用this的话,返回的是全局的
var name = 'The Window'; var obj = { name:'My Object', getName:function(){ return name; } } console.log(obj.getName());
因为此时,这个name根本没和上下文关联,函数直接去找全局的name了
如果返回的是一个函数呢?
这个就是那篇博客中的例子
var name = 'The Window'; var obj = { name:'My Object', getName:function(){ return function(){ return this.name; } } } console.log(obj.getName()());
首先调用getName返回了一个函数,这个函数是
function(){ return this.name; }
我们相当于在全局环境调用了这个函数,所以是全局的name
这个没什么好纠结的。
所以对象成员的话,和闭包没啥关系,因为通过obj.name 和 return this.name 都能访问
如果想给对象增加私有变量,才会用到闭包,且不能通过成员变量来声明。
比如说,年龄age
var obj = { var age = 10; name:'My Object', }
外部是访问不到的
好吧,类是不能这样声明变量的
可以通过构造函数去实现。
function Student(age,name){ //私有变量 var age = age; //公有变量 this.name = name; //公有函数 this.getName = function(){ return this.name; } } var xiaoming = new Student(10,'xiaoming'); console.log(xiaoming.getName());
那小明的age怎么访问呢?
这样行不行?
this.getAge = function(){ return age; }
可以!强吧?
但是,this就不行,因为上面已经表示,类里面没有age这个变量
this.getAge = function(){ return this.age; }
但是如果,全局里又有一个age呢?
var name = 'The Window'; function Student(age,name){ //私有变量 var age = age; this.getAge = function(){ return age; } //公有变量 this.name = name; //公有函数 this.getName = function(){ return this.name; } } var age = 20; var xiaoming = new Student(10,'xiaoming'); console.log(xiaoming.getName());
还是10,那闭包不是多此一举????
var xiaoming = new Student(10,'xiaoming'); var xiaohong = new Student(40,'xiaoming');
还互不影响呢!!! 闭包的意义是啥?
可以通过闭包去访问
function Student(age,name){ //私有变量 var age = age; //访问age this.getAge = function(){ return function(){ return age; } } //公有变量 this.name = name; //公有函数 this.getName = function(){ return this.name; } }
其实和复杂的写法一样
总之就是要返回一个,可以访问到内部变量age的函数,这个函数在哪定义都行
function Student(age,name){ //私有变量 var age = age; //访问age function a(){ return age; } this.getAge = function(){ return a; } //公有变量 this.name = name; //公有函数 this.getName = function(){ return this.name; } }
创建一个setter也可以直接创建
function Student(age,name){ //私有变量 var age = age; this.getAge = function(){ return age; } this.setAge = function(newAge){ age = newAge; } //公有变量 this.name = name; //公有函数 this.getName = function(){ return this.name; } } var age = 20; var xiaoming = new Student(10,'xiaoming');
私有变量、setter、getter这么容易,要闭包干嘛呢?
https://www.cnblogs.com/zxjwlh/p/4420590.html
二、函数里面使用闭包
就是为了访问内部变量,因为函数没有对象那么好用
function f1(){ var n = 999; function f2(){ return n; } return f2; }
应用场景有什么呢?
先了解一个用法,给回调函数显式传参并调用
for(let i=0;i<4;i++){ //当前的i // console.log(i); //执行的回调函数,顺便在执行的时候给他传参 setTimeout(function(a) { //全局的i console.log(a); }(1),1000); }
回调的形参是a,实参是1
最后打印4个1
for(var i=0;i<4;i++){ setTimeout(function() { console.log(i); },1000); }
这个函数的执行
因为setTimeout的执行逻辑,它是异步事件,所以会在同步事件执行完之后再执行,同步事件执行完之后,就是跳出循环,i已经是4了。
这样输出正常了。。
为什么啊?我也不明白
for(var i=0;i<4;i++){ setTimeout(function(i) { console.log(i); }(i),1000); }
用let可以完美解决,因为let是局部变量
for(let i=0;i<4;i++){ setTimeout(function() { console.log(i); },1000); }
解决方法可以参考这篇文章
https://www.jb51.net/article/122489.htm
很好理解,但是文章里面说setTimeout不支持带参数的函数,但是我这边的可以的???
垃圾回收机制
https://blog.csdn.net/yingzizizizizizzz/article/details/77333996
但是还有一点没有说明白,为什么闭包,不会被回收?