js:了解闭包,所向披靡!

好久没更博客啦,最近逛一些论坛,偶尔看一些小伙伴写的闭包文章,看的我泪流满面,动不动就是拿官网的语腔下定义,什么闭包就是一个函数内部的变量能被外部访问,这就是闭包,然后就给你举了例子,例如这样:
function hello(){
var mes="hello sb"
function say(){
alert(mes)
}
return say
}

var a=hello()
a() //弹出 “hello sb”
然后他们就给你解释!看!这mes在函数内部声明的,最后通过外部引用访问到了这个mes!这就是闭包!
是的网上大部分文章就是这样的!我只想说你这样解释和没解释一样!来!我们今天就从源头给说起!给大家做一个详细的解刨!
坐好小板凳!开始了
1.我查了javascript权威指南,在计算机领域,确切的说在javascritp中函数内部的变量能够保存在函数的作用域的这种特性就是闭包!那么照这样说,从技术的角度讲所有的函数都是闭包,因为每个函数都有内部的变量也都能保存在他的作用域中。
那么问题来了,函数的作用域是怎么定义的呢?
js本身采用的词法作用域,词法作用域就是说在函数一开始定义的时候函数的作用域其实整体已经定下来了,在函数执行的时候,它依赖的是自己的作用域!了解这上面的这句话是理解闭包的关键!
假如一个A函数内部我们又定义了另一个A_child函数,在定义的时候这个A_child函数的作用域已经基本定下来了,之后我们在外部任何地方调用A_child函数他之前的作用域都会继承下来(我这只是浅显的的解释),A_child函数并不会因为在A函数外面执行而他的作用域发生重大改变!看例子:

function A(){
   var mes="nihao"
   return {
     A_child:function(mes_child){ //这个函数的作用域中始终有了mes="nihao"的变量定义,不管你在那调用这个函数!
      mes+=mes_child //
      alert(mes)
     }
   } 
}
var ojb=A()
ojb.A_child("小飞飞")  //输出 :"nihao小飞飞" 我在外部调用执行函数,但是他的作用域不会因为在外部调用而改变,会一直继承之前的作用域中声明的所有的变量!

看完这个例子是不是似乎懂点这闭包的所以然了吧!先做个小总结,就是说函数的作用域在函数定义的时候就基本定下来,不管函数在哪里执行,它的作用域中的变量都会继承下来,这样我们用闭包其实就可以保存一些变量,同时相当于有了自己的私有变量,只有我们调用我们函数内部的方法才可以改变它!

上面的这些解释只是我用了一些大白话,和大概的描述让小伙伴先明白闭包的生成过程!下面我们来具体的专业术语刨析这个过程!这是js引擎执行js的一个过程
1.函数在定义的时候,这个函数体内会生成一个scope属性(这个属性仅仅对javascript引擎可见),而这个属性的值就是这个函数的作用域链(作用域链是函数被创建时作用域中对象的集合,如果一个函数被创建,这个函数内部没有嵌套函数,那么这函数作用域链中只有一个对象,那就是全局对象,这个全局对象中就包含了,所有声明的变量,声明的函数,声明的函数也可以作为全局对象的属性看待)。
2.在函数执行的时候,首先在函数内部会自动生成一个“运行期上下文”的内部对象,而且这个对象会有自己的作用链,用来做变量解析。
这个“运行期上下文”对象的作用域链是继承的函数定义时候的作用域链。同时在函数执行的时候会产生另一个活动对象,(这个活动对象是有函数执行的时候所有的声明的变量和参数组成)并且这个活动对象会被追加到这个“运行期上下文对象”的作用域链中的最前端!
3.作用域链是用来做变量解析的,而变量解析其实就是函数在执行的时候它碰见一个变量,首先会程作用域链顶端的第一对象中查找,改变量是否在这个对象中,如果找不到就会从作用域链中的 第二个对象中查找,依次类推,到最后的全局对象中也没找到就报错!
再总结下这些术语,函数执行依赖作用域,作用域的范围由函数临时生成的“运行期下文”对象中的作用域链确定,而这个对象的作用域链是由通过(继承函数定义时的作用域链)和(函数执行临时生成的活动对象追加到作用域链的最前端)共同组成的。而这些都具备了,函数执行开始做变量解析,其实就在作用域链中一个对象一个对象中寻找,当前的变量是否在这个作用域链对象中,没在,向上级继续直到找到为止
闭包的整个形成过程已经告诉你们啦
函数内部的变量可以保存在函数的作用域中的这种特性就是闭包!而我们通常解释说闭包就是一个函数内部的变量能被另一个函数访问,这个函数就是闭包,其实这个解释不是在解释闭包是什么,而是解释利用闭包能做什么!所以你看这样的解释永远不会明白闭包是什么!网上大部分教程,博客,他们给你解释闭包,而没有告诉你什么是作用域链,作用域链如何形成,其实他们自己也不懂真正的闭包是啥!他们只告诉你!看啊,我刚写的那个函数就是闭包!我呵呵!
如果这样你还看不太懂,请看三遍!并回头补充自己的基础知识,我文中提到的词汇有些不懂请去查,我只能做到这了
哦,网上那些解释闭包的时候总会给你附上这样一个经典的题目

“`
var lists=document.getElementByTagsNams(“li”)
//假如由四个li
function addClicks(){
for(var a=0;a

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值