zoukankan      html  css  js  c++  java
  • 闭包 构建函数 简单工厂模式

    首先说说闭包,闭包在我们实际开发中处处被用到,那个它到底是个什么东西呢?

    var user=(function(){
        var USER={
          name:"mapleTao",
          password:"123456"
        }
        return {
          getName:function(){
            return USER.name;
          },
          getPassword:function(){
            return USER.password;
          }
        }
      })();
      console.log(user.getName())
      console.log(user.getPassword())
      console.log(USER)
    

      

    上面就是一个简单的闭包,输出结果为mapleTao,123456,error;让我们先来解析下这个例子干了什么,我们先声明了一个叫user的变量,后面是一个闭包,闭包分成两部分,一部分是前面的匿名函数,后面是该函数的调用,简单点说就是立即执行了这个函数并返回一个对象。对象中包括了两个获取值的方法。在js中是没又常量这也说法的,但是呢,因为js是一门比较灵活的语言,所以呢我们通过闭包就创建了一个这样的“常量”,上面的例子只提供给你获取值的方法,但是呢,你并不能修改USER的内容,这个像不像java中的常量呢?

    变量又两种,一种是全局变量,一种是局部变量,我们都知道全局变量是在所有的地方都能访问到,这是比较危险的,因为所有人都能修改它,它的作用域太大了。还有一种是局部变量,顾名思义,局部变量就是一个小区域的变量,我们能在函数内部找到它,但是在外面你是找不到它的。闭包就可以做到让我们在函数外部访问到函数内部的变量。

    闭包的好处:

    1:不会污染全局变量。上面这个例子中是无法直接访问到user的

    2:让一个变量永久保存到内存中,不会被回收系统回收掉。我们能通过它提供的方法访问到它,说明它是保存到内存中的而且也没有被清掉

    3:创建立即执行。

    4:形成一个独立的作用域。上面这个例子中,匿名函数内部就是一个独立的作用域,这个作用域里面的变量外部无法直接获取。

    缺点

    1:占内存。因为它不会被gc回收,所以会占内存空间,严重可能会导致内存泄漏。

    2:外部可以改变内部函数的值。

    闭包: 函数外可以访问到函数内部的变量。

    通过他的解释就知道闭包的使用了,就是你需要使用到的变量,但是这个变量不能被直接访问,就比如比较函数:

    // @pramater name string
    function
    compare(name){ return function (n,m) { if (name) { n = n.name m = m.name } if (n>m) { return 1 }else if (n == m) { return 0 }else if (n < m) { return -1 } } }

    上述比较函数提供一个name值来,可以根据对象的属性或者对象本身进行排序。

    接下来聊聊构造函数,js中虽没有类的说法,但是呢我们可以通过不同的方法来让它实现这个效果。不多说上代码。

     function Book(name,type,author){
        if(this instanceof Book){
          this.name=name;
          this.type=type;
          this.author=author;
        }else{
          return new Book(name,type,author);
        }
      };
      Book.prototype={
        introduce:function(){
          console.log(this.name+"--"+this.type+"--"+this.author);
        }
      };
    
      var HTML=new Book("h5开发","Book","maple");
      var js=Book("设计模式","Book","tao");
     
      HTML.introduce();
      js.introduce();

    上面这段代码就是一个简单的构造函数,通过构造函数,生成相似的对象。简单来说构造模式就是用来创建相似对象的函数,也就是对一些相同代码的封装,简单点来说就是优化,将一些重复使用的代码抽象出来。这个可以减少代码量,增加代码的复用性。

    上面这个构造函数也用到了原型模式,原型模式在我看来也是一种优化,因为对象的原型是一个引用类型,引用类型比较特殊,它是指向堆的,所以不会重复分配内存,可以减少内存的占用率,而且prototype是一个函数自带的属性,写在里面可读性更强。

      //报纸
      function Newspaper(name,type,author){
        if(this instanceof Newspaper){
          this.name=name;
          this.type=type;
          this.author=author;
        }else{
          return new Newspaper(name,type,author);
        }
      };
      Newspaper.prototype={
        introduce:function(){
          console.log(this.name+"--"+this.type+"--"+this.author);
        }
      };
      //杂志 
      function Magazine(name,type,author){
        if(this instanceof Magazine){
          this.name=name;
          this.type=type;
          this.author=author;
        }else{
          return new Magazine(name,type,author);
        }
      };
      Magazine.prototype={
        introduce:function(){
          console.log(this.name+"--"+this.type+"--"+this.author);
        }
      };

    上面我们又创建了两个构造函数,一个是报纸构造函数,一个是杂志构造函数,但是如果你交给别人用的话,不可能给对方三个函数,而且在用法方面可能会有点问题,所以这个时候我们的封装一下。提供一个接口。

    我们用简单工厂模式封装下以上代码。

    var createFactory=function(name,type,author){
        var obj;
        switch(type){
          case "Book":
            obj=new Book(name,type,author);
            break;
          case "Newspaper":
            obj=new Newspaper(name,type,author);
            break;
          case "Magazine":
            obj=new Magazine(name,type,author);
            break;
        }
        return obj;
      };
      var mag=createFactory("剎漫画","Magazine","漫画");
      var news=createFactory("新闻","Newspaper","新闻");
      var bk=createFactory("一本书","Book","书");
      console.log("-------------");
      mag.introduce();
      news.introduce();
      bk.introduce();
      console.log("-------------");

    上面就是一个简单的工厂模式,createFactory就是一个书店,但我们去买书的时候,就知道告诉它我们买一本杂志或者报纸啊,后面的就交给书店老板解决了。

    上面三个函数有很多共同点,这个时候我们可以进一步的优化代码,我们可以把相同的抽象出来来,不同的再判断,如下。

    var createBook=function(name,type,author){
        var o={};
        o.name=name;
        o.type=type;
        o.author=author;
        o.introduce=function(){
          console.log(this.name+"--"+this.type+"--"+this.author+"--"+this.status);
        }
        if(type==="Book"){
          o.status=0;
        }
        if(type==="Magazine"){
          o.status=1;
        }
        if(type ==="Newspaper"){
          o.status=2;
        }  
        return o;
      }
      var mag1=createBook("剎漫画","Magazine","漫画");
      var news1=createBook("新闻","Newspaper","新闻");
      var bk1=createBook("一本书","Book","书");
      mag1.introduce();
      news1.introduce();
      bk1.introduce();

    但是,从上面这段代码来看,但对象很多时会特别复杂,很难维护,而且introuce每次都会去实例一次,所以还可以想办法再优化下。

    今天就先到这里,咋先去休息下。更多精彩请听下回分解。

  • 相关阅读:
    23 数字时钟&长图滚动
    22 日期特效&长图滚动
    彻底澄清c/c++指针概念
    已管理员模式运行批处理路径丢失问题的解决方法
    使用mathjax在博客中完美显示数学公式,支持PC,手机浏览器
    GOOGLE高级搜索技巧
    我要搬家
    简单的3proxy配置
    AutoMapper小结
    专业IT培训机构-传智播客
  • 原文地址:https://www.cnblogs.com/mapletao/p/6067937.html
Copyright © 2011-2022 走看看