前端闭包机制详解

在谈闭包之间,我们先看一下javascript的作用域,我们以函数举例。

对一个函数来说它的作用域分为三种:

函数定义作用域

函数调用作用域、

函数内部作用域

以下是一段代码:

var x="how are you";

var a=0;

function ab(){

       console.log('a=',a);

        console.log('x=',this.x);

}

function ac(){

      var a=100;

      var x="I'm fine";

      ab();

}

ac();

ab();

以下为输出:

函数ac的输出与函数ab的输出一致,这是不是很奇怪?函数ac中定义了同名变量a=100,x="I'm fine",ac中调用了函数ab,但函数ab的输出并没有受到影响。

我们来看看《javascript权威指南》中对闭包的解释,闭包就是调用一个函数时,如果该函数内函数体有对函数外变量的引用,函数被调用时,就是会将函数以及函数引用的变量包裹起来,这就形成了闭包。

我们再来看上面的例子,这是js闭包的经典示例,我们不难发现,js中对于函数的调用会回溯到函数定义时的作用域,函数的作用域就是函数定义的作用域,它和函数调用的作用域无关。所以无论函数ac内变量怎么变换,都不会影响ac内函数ab的输出。

那么,在函数调用作用域与定义作用域不同的情况下,如果我们想让函数的掉哦用作用域可以影响函数的输出有什么办法吗?

答案时肯定的,方法可以从两个方面入手:

方案一:函数传参

方案二:改变函数执行上下文

我们先来看方案一怎么实现的,以下是示例代码:

var a='how are you';

function ab(a){

      console.log('a=',a);

}

function ac(){

      var a="I'm fine";

      ab(a);

}

ab(a);

ac(a);

输出:

通过输出可以看出函数ab的输出发生了改变,这是因为在函数ac中变量a被当作参数传入了函数ab。再看函数ac的写法是不是很熟悉,这就是常见的回调函数的写法,回调函数在异步javascript应用很多。在函数ac中函数ab的调用,严格意义上算不上闭包,因为ac只调用了ab本身,没有连ab外的变量一起调用。

我们再来看改变函数执行上下文怎么实现:

var x="how are you";

function ab(){

      console.log("x=",this.x);

}

var a={

      x:"i'm fine"

};

ab();

ab.call(a);

以下是输出结果:

ab的输出更改成功, 在js中使用call,apply以及bind这些方法可以改变函数执行的上下文。

总结,js中的闭包如果想通了其实很简单,就是一个函数如果被调用的话,它不是在调用它的作用域执行的,而是在定义函数的作用域执行的。理论上在不改变函数执行上下文的情况下,只有定义函数的作用域以及函数内部作用域可以影响函数的输出,调用函数的作用域要想影响函数的输出,只有三个方法,第一个调用函数作用域以及定义函数作用域是同一个作用域(这个纯属扯淡,是个人都知道),第二个是调用函数作用域将参数传进函数内部作用域,第三个是通过apply,call以及bind这些方法改变函数执行的上下文。我现在还想到了第四个方法,时间有限,不说了,以后在补充。

第一次写技术文章,难免有很多遗漏的地方,如果这篇文章能有幸给人看到的话,希望您能留下宝贵的意见。

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

推荐阅读更多精彩内容

  • 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。 一、变量...
    zock阅读 1,075评论 2 6
  • ● 闭包基础 ● 闭包作用 ● 闭包经典例子 ● 闭包应用 ● 闭包缺点 ● 参考资料 1、闭包基础 作用域和作...
    lzyuan阅读 930评论 0 0
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile丽语阅读 3,830评论 0 6
  • 为什么你睡了11个小时仍然觉得疲累?为什么你花了好几万去岛国度假并没有增加生活的热情? 休息的真正含义是什么?是恢...
    小梳子0725阅读 240评论 2 6
  • 清晨迎着朝阳 夜里披着星光 你疯狂地奔跑 在逐梦的路上 不怕万人阻挡 只怕自己...
    涛心依旧阅读 684评论 0 3