以前看到别人用了闭包的代码,就以为是函数里面套函数,今天专门去看了一下阮一峰的闭包笔记,进去就发现一处不合适
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量
只有JavaScript函数内部可以直接读取全局变量?感受到了这句话森森的不合适啊。
也学到了一个点,不用var定义的变量原来就是一个全局变量啊,我以前都木有发现,遁地
正文
抛出来两段代码,先别忙着理解
var f1 = function(){
var name = "chichi";
return function f2() {
console.log( this.name );
}
}
var name = "zhangchi"
var bar = f1()() // zhangchi
var f1 = function(){
var name = "chichi";
return function f2() {
console.log( name );
}
}
var name = "zhangchi"
var bar = f1()() // chichi
注:一定有人觉得f1()()有点点晦涩难懂,来我们把这句话拆开:
var a = f1();
var bar = a();
我们执行f1的时候把f2函数给return了,这个时候a就是这个闭包函数f2啦,我们再a()就把a给执行了,结果返回给bar。写成f1()()为了最后埋下伏笔==
闭包的概念
JavaScript | MDN
Closures (闭包)是使用被作用域封闭的变量,函数,闭包等执行的一个函数的作用域。通常我们用和其相应的函数来指代这些作用域。(可以访问独立数据的函数)
那大概是指访问那些封闭的作用域的变量或者函数,楼上的两个例子中f1指的就是封闭的局部变量,f2就是闭包函数
闭包的作用
- 从外部访问局部变量
- 内存的浪费
- 数据的隐藏和封装
从外部访问局部变量
如最开始的两个例子中所见
内存的浪费
上文中提到其实原型继承也能实现功能,在非必要的时候我们要避免闭包,毕竟为每个对象赋值一次闭包函数造成了内存的浪费,继承的原型可以为所有对象共享,且不必在每一次创建对象时定义方法。
数据的隐藏和封装
var f1 = function(){
var n = 1;
function addSelf() {
n += 1
}
return function f2() {
addSelf(n)
return n;
}
}
var bar = f1()
var value = bar() // 2
value = bar() // 3
如上我们的f1具有了私有属性n和函数addSelf,只有在同一闭包空间f2才可以访问,这种形式的闭包提供了许多通常由面向对象编程所享有的益处,尤其是数据隐藏和封装。(摘自MDN)
原型链和闭包
var animals = function(name, sound) {
this.name = name;
this.sound = sound;
return isSame = function(obj) {
if(this.sound === obj.sound) {
return true;
} else {
return false;
}
}
var dogJack = new animals("dogJack", "wang");、
var dogKitty = new animals("dogKitty", "wang");
dogJack(dogKitty)
var f1 = function(){
var name = "chichi";
return function f2() {
console.log( name );
}
}
var a = new f1();
a() // chichi
看得出来dogJack是继承了animals.prototype,这和我们的闭包有什么关系呢?
其实,dogJack就是isSame,那么,animals中的name就被isSame继承过去了,isSame是可以访问的到的。或者说name是在animals的全局中的,isSame是可以访问的到的。其实闭包的外部访问内部变量利用的就是原型链的继承啦。但是也有不同,在每次构造器被调用时,方法都会被重新赋值一次即是为每一个对象的创建。
看到这个闭包的知识点的时候,就想起来阿里的一个笔试题了
function add(a) {
var sum = a;
return function add1(b) {
sum += b;
return function add2(c) {
sum += c;
return sum;
}
}
}
var result = add(1)(2)(3);
console.log(result); // 6
不记得是不是这样的还是比这个难来着,当时还很弱很弱。。。