码迷,mamicode.com
首页 > 其他好文 > 详细

闭包 构建函数 简单工厂模式

时间:2016-11-16 02:13:20      阅读:291      评论:0      收藏:0      [点我收藏+]

标签:地方   匿名   actor   rip   user   color   输出   引用类型   img   

今天收获比较多,仿佛无意中打通了七筋八脉,想通了一些原理性的东西。对js有了更深的理解。

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

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:外部可以改变内部函数的值。

接下来聊聊构造函数,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每次都会去实例一次,所以还可以想办法再优化下。

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

闭包 构建函数 简单工厂模式

标签:地方   匿名   actor   rip   user   color   输出   引用类型   img   

原文地址:http://www.cnblogs.com/mapletao/p/6067937.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!