JS闭包

数学中的闭包与JS闭包

首先需要认识到一点,数学闭包和JS闭包是没有关系的。

数学上,闭包是指一个集合在某个运算下闭合,也就是对该集合进行某种运算,得到的结果仍属于该集合。
在JS中,百度百科援引官方的解释是:“闭包”指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。听起来有些难懂,那就让我们继续向下看吧。

闭包和什么有关系?

  • 作用域:
    在JS中,变量的作用域有两种,局部变量和全局变量。在函数内部可以访问函数外定义的变量,但在函数外部却不能访问函数内部的变量,这是JS的作用域在作怪。
let n = 'Hello!' ;
function a(){
    var m = 'Bob.' ;//此处的var不能省略,如果省略,m就会变成全局变量。
    console.log(n) ;
}
a();//Hello!
console.log(m);//error

上面的例子中,n是全局变量,作用于全局;
m是局部变量,作用于函数a的内部;
在函数内部可以正常输出n的值,但在函数外部却无法正常访问函数内部定义的变量。

  • 作用域链:
    看个例子,摘自CSDN的博客(Skycrab)
name="lwy";
function t(){
    varname="tlwy";
    functions(){
    varname="slwy";
    console.log(name);
    }
    functionss(){
    console.log(name);
    }
    s();
    ss();
}
t();

执行t()时,作用域链是:t()->window
执行s()时,作用域链是: s()->t()->window,所以name是”slwy";
执行ss()时,作用域链是: ss()->t()->window,所以name是”tlwy";

function createFunctions(){
    var result =newArray();
    for(var i=0; i < 10; i++){
        result[i] =function(){
        return i;
    };
}
return result;
}
var funcs = createFunctions();
for(var i=0; i < funcs.length; i++){
    console.log(funcs[i]());
}

输出10个10;WHY?
函数带()才是执行函数!
单纯的一句 var f = function() { alert('Hi'); }; 是不会弹窗的,后面接一句 f(); 才会执行函数内部的代码。类比上面的例子,也就是说,内部的函数在定义的时候就是在添加作用域链,循环的时候导致上级的i=10,然后在执行的时候,直接从顶级找到i,输出的自然就是10。
那怎么解决呢?

···
for(var i=0; i < 10; i++){
        function num(i){
            return function(){
                return i;  
        }
result[i] = num(i);
};
···
  • with语句。with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。
person={name:"yhb",age:22,height:175,wife:{name:"lwy",age:21}};
with(person.wife){
console.log(name);
}

with语句将person.wife添加到当前作用域链的头部,所以输出的就是:“lwy".
with语句结束后,作用域链恢复正常。

闭包如何解决外部访问内部的变量的问题?

function a(){
    var m = 'Bob.' ;
    function b(){
        console.log(m);
    }
    return b;
}
var A = a();
A();//Bob.

该例子中的b()就是闭包。从上面的例子中可以看出,我们将内部变量通过嵌套一个内部函数b,在b中进行操作最后将b返回出去。这样在外部就可以访问到内部的变量了。

闭包的作用一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中(因为a()内部的函数b()的执行要依赖a()中定义的变量)。

在“脚本之家”里面有一个特别好的例子,如下所示:

function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result();// 999
nAdd();
result();// 1000

result实际上是函数f2;
nAdd是匿名函数且是全局变量,它本身也是一个闭包,在函数外部对函数内部的局部变量进行操作。

一些例子:

  • (1)
var name = "name";
var people = {
    name : "peopleName",
    getName : function(){
        return function(){
            return this.name;
        };
    }
};
alert(people.getName()());//The Window
  • (2)
function outerFun()
{
    var a=0;
    function innerFun()
    {
        a++;
        alert(a);
    }
return innerFun;//注意这里
}
var obj=outerFun();
obj();//结果为1
obj();//结果为2
var obj2=outerFun();
obj2();//结果为1
obj2();//结果为2
  • (3)
function outerFun()
{
    var a =0;
    alert(a);
}
var a=4;
outerFun();
alert(a);

结果是0,4. 因为在函数内部使用了var关键字 维护a的作用域在outFun()内部.

  • (4)
function outerFun()
{
    //没有var
    a =0;
    alert(a);
}
var a=4;
outerFun();
alert(a);

结果为0,0

闭包的缺点:

不必要的闭包会徒增内存消耗!
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 162,158评论 4 370
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,600评论 1 307
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,785评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,655评论 0 220
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 53,075评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 41,002评论 1 225
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,146评论 2 318
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,918评论 0 211
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,671评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,838评论 2 254
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,318评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,636评论 3 263
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,343评论 3 244
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,187评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,982评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,126评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,934评论 2 279

推荐阅读更多精彩内容