关于闭包的理解

由于之前在上学的时候,发现老师对着答案讲题目特别的溜。因此写文章以前,我去把查了一下闭包的概念,我将我对闭包的理解尽可能往官方解释上面凑,结果凑到最后,依旧无法用通俗的语言去解释这个概念。那么我仍是讲讲我理念上的闭包吧 。面试

我理解的闭包:一个(存于内存的)封装好的数据或方法。ajax

先讲封装好的固定数据,举个栗子:闭包

function testOne() {
 return 1 ;
 }
 var NumOne = testOne();
 console.log(NumOne);//1

上面这个栗子就是我对闭包的一部分理解。
在说下面的话题以前,必须又得提到一个关于‘()’的理解。
个人理解上:
1 . ()的意思能够理解成 '执行';函数赋值的时候是不用带上()的,执行的时候才须要。异步

举个栗子:函数

(function test(){console.log('hello Wolrd'})();//hello world

这实际上就等同于:this

function test(){console.log('hello Wolrd'};
test();//hello world

2 . ()中能够带入参数,参数能够用于做为闭包函数执行时候的某个常量,这个常量对于外部来讲是个变量。这样说可能有点绕,那么说句广告词可能会好理解点:开局只有一把武器...那么这武器,也就是()中的参数,它在游戏开始以前是一个变量,你能够选择矛,锤...可是进入游戏以后,这把武器就不能够改了,当你执行操做的时候,选择了矛的操做矛的属性,选择了锤的只能操做锤的属性。线程

结合()的第二个特征,再说一个封装好的动态数据,代码以下:code

var spear = {operation:'刺'};
var hammer = {operation:'挥'};
function con_opera(t) {
return (t.operation);
}
console.log(con_opera(spear)); //刺
console.log(con_opera(hammer)); //挥

3.()的参数能够为多个,包括this,window,event等。对象

结合()的第三个特征,再端盘关于封装好的方法的栗子:游戏

function plusFn(a,b){
console.log(a+b);
}
plusFn(3,4);//7

关于我对闭包的用途的理解 。

1.面向对象。

若是说如今如今有不少个玩家进游戏选角色的时候要捏人,若是从过程上去处理,那无疑是不够灵活的。
若是从对象上处理呢?
①.便于复用:
捏头(头部属性);捏身子(身子属性);捏手(手部属性);捏腿(腿部属性);
这样的话,只要写四个方法,就能够拼接成一个捏人的方法。并且能够重复使用这套方法,构成结构的多样性。
②.便于代码维护:
若是想要在身上捏对翅膀的话,彻底能够再多加一个捏翅膀(翅膀属性);

2.异步处理。
由于闭包使用的是参数,而不闭包使用的是变量,以前解释过,参数为函数内部的常量,这个值在调用闭包的时候已经设置好,不会随着外界变量的改变而改变。
还有个是我的的习惯问题,我更喜欢的是写好一个方法,而后处处使用,尤为是ajax的时候,获得参数的处理方法,success的时候 fun(返回值),error的时候 fun(默认值),并且因为js的单线程多进程,频繁切换进程但同一进程倒是按照顺序执行,这样的话,将方法闭包放入一个进程里面能够既方便又有效地避免异步引起的bug。

3.方便回调

从前有座山,山上有座庙,瞄里有个老和尚,老和尚给小和尚讲故事:。。。
这就是无限循环就是个回调函数。

(function test(){
 console.log('从前有座山,山上有座庙,瞄里有个老和尚,老和尚给小和尚讲故事:');
 test();
 })();

闭包题的分析:
这里从网上找了俩道比较经典的面试题,由于我实在也不知道它们初始出处是哪里,原谅我无法写引用地址。
1.

for(var i = 1; i <= 5; i++) {
   setTimeout( function () {
      console.log(i);
      }, 1000 );
    } //5 5 5 5 5

改写一下:

function test(t){
setTimeout( function () {
      console.log(t);
      }, 1000 );
}
 for(var i = 1; i <= 5; i++) {
   test(i);
   } //1,2,3,4,5

这个就是异步的问题,若是使用闭包,闭包被调用的时候,console.log()分配的参数则是1,2,3,4,5这五个常量。而不闭包,则是瞬间去给五个console.log()分配了变量i,而i在内存中是一个变量,在setTimeout设定的时间到达时,已是5了,这也是为何一会儿输出5个5的缘由。

2.

function fun(n,o) {
  console.log(o)
  return {
    fun:function(m){
      return fun(m,n);
    }
  };
}
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);

说实话,第一次作这题的时候,感受在坐升降机,又像在看无限放大的漩涡。
return的意思为返回值,返回值的意思就一个函数的处理结果:加水(糖){return ‘糖水’}

a = fun(0);//fun(0,o),此时o为undefined,
因此console.log 一个 undefined 
并
return {fun:function(m)}
则
a = {
fun:function(m){
    return fun(m,0);
    }
}
a.fun(1) = function(1){
  return fun(1,0);
};
fun(1,0) = {
    console.log(0);
  return {
         fun:function(m)
         }
};//因此会console.log一个0
a.fun(2)与a.fun(3)同a.fun(1);

关于b fun(0).fun(1) == a.fun(1)//到这层为止,请参照a.fun(1)的解释。因此会console.log undefined,0;
fun(0).fun(1).fun(2)//这层 
fun(0).fun(1) = {
console.log(0);    
return{
        fun:function(m){
            return fun(m,1);
          }
      }
}则fun(0).fun(1).fun(2) = fun(2,1); //运行到fun(0).fun(1).fun(2)这层
fun(2,1) = {
    console.log(1);
     return {
             fun:function(m)
                 {
                  return fun(m,2);
                 }
            }
  }//因此会console.log一个1
  则fun(0).fun(1).fun(2).fun(3) = fun(3,2);//同理于fun(2,1),因此会console.log一个2
  
  //那么c这边就好解决的多了。
  c = fun(0).fun(1) //相似于a.fun(1); 因此会console.log undefined,0;
  c.fun(2)与c.fun(3)//参考b 的fun(0).fun(1).fun(2) ,因此会console.log 1,1.
  
  //因此最后答案为 undefined,0,0,0;undefined,0,1,2;undefined,0,1,1

以上就是我我的对闭包的不太全面的理解,写下来主要是为本身之后作个记念,若是能帮助一些人则更为开心,有理解不足的地方但愿你们多多提意见。

相关文章
相关标签/搜索