zoukankan      html  css  js  c++  java
  • 关于闭包的一点探索

     看前两章即可

    https://www.cnblogs.com/xiangqianjin/p/6595115.html

    一、闭包用来访问内部变量

    但是对于对象来说,直接return this.xxx也可以访问

    var name = 'The Window';
    
    var obj = {
    
      name:'My Object',
      getName:function(){
        return this.name;
      }
    
    }
    
    console.log(obj.getName());

    如果直接return name,没用this的话,返回的是全局的

    var name = 'The Window';
    
    var obj = {
    
      name:'My Object',
      getName:function(){
        return name;
      }
    
    }
    
    console.log(obj.getName());

    因为此时,这个name根本没和上下文关联,函数直接去找全局的name了

    如果返回的是一个函数呢?

    这个就是那篇博客中的例子

    var name = 'The Window';
    
    var obj = {
    
      name:'My Object',
      getName:function(){
        return function(){
          return this.name;
        }
      }
    
    }
    
    console.log(obj.getName()());

    首先调用getName返回了一个函数,这个函数是

    function(){
          return this.name;
        }

    我们相当于在全局环境调用了这个函数,所以是全局的name

    这个没什么好纠结的。

    所以对象成员的话,和闭包没啥关系,因为通过obj.name 和 return this.name 都能访问

    如果想给对象增加私有变量,才会用到闭包,且不能通过成员变量来声明。

    比如说,年龄age

    var obj = {
    
      var age = 10;
      name:'My Object',
      
    }

    外部是访问不到的

    好吧,类是不能这样声明变量的

     可以通过构造函数去实现。

    function Student(age,name){
      //私有变量
      var age = age;
      //公有变量
      this.name = name;
      //公有函数
      this.getName = function(){
        return this.name;
      }
    }
    
    var xiaoming = new Student(10,'xiaoming');
    
    console.log(xiaoming.getName());

    那小明的age怎么访问呢?

    这样行不行?

     this.getAge = function(){
        return age;
      }

    可以!强吧?

    但是,this就不行,因为上面已经表示,类里面没有age这个变量

    this.getAge = function(){
        return this.age;
      }

    但是如果,全局里又有一个age呢?

    var name = 'The Window';
    
    function Student(age,name){
      //私有变量
      var age = age;
    
      this.getAge = function(){
        return age;
      }
      //公有变量
      this.name = name;
      //公有函数
      this.getName = function(){
        return this.name;
      }
    }
    
    var age = 20;
    
    var xiaoming = new Student(10,'xiaoming');
    
    console.log(xiaoming.getName());

    还是10,那闭包不是多此一举????

    var xiaoming = new Student(10,'xiaoming');
    var xiaohong = new Student(40,'xiaoming');

    还互不影响呢!!! 闭包的意义是啥?

    可以通过闭包去访问

    function Student(age,name){
      //私有变量
      var age = age;
      //访问age
      this.getAge = function(){
        return function(){
          return age;
        }
      }
      //公有变量
      this.name = name;
      //公有函数
      this.getName = function(){
        return this.name;
      }
    }

    其实和复杂的写法一样

    总之就是要返回一个,可以访问到内部变量age的函数,这个函数在哪定义都行

    function Student(age,name){
      //私有变量
      var age = age;
      //访问age
      function a(){
        return age;
      }
    
      this.getAge = function(){
        return a;
      }
      //公有变量
      this.name = name;
      //公有函数
      this.getName = function(){
        return this.name;
      }
    }

    创建一个setter也可以直接创建

    function Student(age,name){
      //私有变量
      var age = age;
    
      this.getAge = function(){
        return age;
      }
    
      this.setAge = function(newAge){
        age = newAge;
      }
    
      //公有变量
      this.name = name;
      //公有函数
      this.getName = function(){
        return this.name;
      }
    }
    
    var age = 20;
    
    var xiaoming = new Student(10,'xiaoming');

     

    私有变量、setter、getter这么容易,要闭包干嘛呢?

    https://www.cnblogs.com/zxjwlh/p/4420590.html

    二、函数里面使用闭包

    就是为了访问内部变量,因为函数没有对象那么好用

    function f1(){
      var n = 999;
      function f2(){
        return n;
      }
      return f2;
    }

    应用场景有什么呢?

    先了解一个用法,给回调函数显式传参并调用

    for(let i=0;i<4;i++){
      //当前的i
      // console.log(i);
      //执行的回调函数,顺便在执行的时候给他传参
      setTimeout(function(a) {
        //全局的i
        console.log(a);
      }(1),1000);
    }

    回调的形参是a,实参是1

    最后打印4个1

    for(var i=0;i<4;i++){
      setTimeout(function() {
        console.log(i);
      },1000);
    }

    这个函数的执行

    因为setTimeout的执行逻辑,它是异步事件,所以会在同步事件执行完之后再执行,同步事件执行完之后,就是跳出循环,i已经是4了。

     这样输出正常了。。

    为什么啊?我也不明白

    for(var i=0;i<4;i++){
      setTimeout(function(i) {
        console.log(i);
      }(i),1000);
    }

    用let可以完美解决,因为let是局部变量

    for(let i=0;i<4;i++){
      setTimeout(function() {
        console.log(i);
      },1000);
    }

    解决方法可以参考这篇文章

    https://www.jb51.net/article/122489.htm

    很好理解,但是文章里面说setTimeout不支持带参数的函数,但是我这边的可以的???

    垃圾回收机制

    https://blog.csdn.net/yingzizizizizizzz/article/details/77333996

    但是还有一点没有说明白,为什么闭包,不会被回收?

  • 相关阅读:
    Laravel5.1 搭建简单的社区(十一)--上传头像
    Laravel5.1 搭建简单的社区(十)--实现下拉菜单
    Laravel5.1 搭建简单的社区(九)--发表评论
    Laravel5.1 搭建简单的社区(八)--展示评论
    Laravel5.1 搭建简单的社区(六)--修改文章
    git 批量删除远程分支
    如何在vscode中调试代码
    【CSS黑科技2】CSS百分比实现高度占位自适应(margin/padding)
    sourceTree 更新svn提示can't locate SVN/Core.pm
    【CSS黑科技1】使用CSS的currentColor变量写DRY代码
  • 原文地址:https://www.cnblogs.com/weizhibin1996/p/9700038.html
Copyright © 2011-2022 走看看