JavaScript设计模式一:工厂模式和构造器模式

什么是模式

前阵子准备期末考试,挺累也挺忙的,实在闲不得空来更新文章,今天和你们说说javascript中的设计模式。javascript

首先呢,咱们须要知道的是:模式是一种可复用的解决方案,而反模式呢就是针对某个问题的不良解决方案。java

js反模式常见例子

  • setTimeoutsetInterval传递字符串,而不是函数,这会触发eval()的内部使用。
  • 在全局上下文中定义大量的变量污染全局命名空间
  • 修改Object类的原型
  • 之内联形式使用js,嵌入在HTML文件中的js代码是没法包含在外部单元测试工具中的。
  • 滥用document.write,若是在页面加载完成后执行docume.write,它会重写咱们所在的页面,可使用document.creatElement代替的话就尽可能不用docume.write

设计模式的类别

建立型设计模式

建立型设计模式专一于处理对象建立机制,以适合给定状况的方式来建立对象。属于这个类别的属性包括:设计模式

Constructor构造器、Factory工厂、Abstract抽象、Prototype原型、Singleton单例和Builder生成器

结构型设计模式

结构型模式与对象组合有关,一般能够用于找出在不一样对象之间创建关系的简单方法。
属于这个类别的模式包括:函数

Decorator装饰者、Facade外观、Flyweight享元、Adapter适配器和Proxy代理

行为设计模式

行为模式专一于改善或简化系统中不一样对象之间的通讯。工具

行为模式包括:单元测试

Iterator迭代器、Mediator中介者、Observer观察者和Visitor访问者

Factory(工厂)模式

为了解决多个相似对象声明的问题,咱们可使用一种叫作 工厂模式的方法,这种方法 就是为了解决实例化对象产生大量重复的问题。测试

<script type="text/javascript">
    function createObject(name,age,profession){//集中实例化的函数
        var obj = new Object();
        obj.name = name;
        obj.age = age;
        obj.profession = profession;
        obj.move = function () {
            return this.name + ' at ' + this.age + ' engaged in ' + this.profession;
        };
        return obj;
    }
    var test1 = createObject('trigkit4',22,'programmer');//第一个实例
    var test2 = createObject('mike',25,'engineer');//第二个实例
    alert(test1.move());
    alert(test2.move());
</script>

工厂模式的分类

工厂模式分为简单工厂、抽象工厂和智能工厂,工厂模式不显示地要求使用一个构造函数。ui

简单工厂模式:使用一个类(一般为单体)来生成实例。
复杂工厂模式:使用子类来决定一个成员变量应该是哪一个具体的类的实例。this

工厂模式之利

主要好处就是能够消除对象间的耦合,经过使用工程方法而不是new关键字。将全部实例化的代码集中在一个位置防止代码重复。

工厂模式之弊

大多数类最好使用new关键字和构造函数,可让代码更加简单易读。而没必要去查看工厂方法来知道。

工厂模式解决了重复实例化的问题 ,但还有一个问题,那就是识别问题,由于根本没法 搞清楚他们究竟是哪一个对象的实例。prototype

alert(typeof test1); //Object 
alert(test1 instanceof Object); //true

什么时候使用工厂模式?

Factory模式主要在如下场景使用:

  • 当对象或组件涉及高复杂性时
  • 当须要根据所在的不一样环境轻松生成对象的不一样实例时
  • 当处理不少共享相同属性的小型对象或组件时

Constructor(构造器)模式

ECMAScript 中能够采用构造函数(构造方法)可用来建立特定的对象。 该模式正好能够解决以上的工厂模式没法识别对象实例的问题。

<script type="text/javascript">
    function Car(model,year,miles){//构造函数模式
        this.model = model;
        this.year = year;
        this.miles = miles;
        this.run = function () {
            return this.model + " has done " + this.miles + "miles";
        }
    }
    var Benz = new Car('Benz',2014,20000);
    var BMW = new Car("BMW",2013,12000);
    alert(Benz instanceof Car); //很清晰的识别他从属于 Car,true
    
    console.log(Benz.run());
    console.log(BMW.run());
</script>

使用构造函数的方法 ,即解决了重复实例化的问题 ,又解决了对象识别的问题,该模式与工厂模式的不一样之处在于:

1.构造函数方法没有显示的建立对象 (new Object()); 
2.直接将属性和方法赋值给 this 对象;
3.没有 renturn 语句。

构造函数的方法有一些规范:

1.函数名和实例化构造名相同且大写, (PS:非强制,但这么写有助于区分构造函数和 普通函数);
2.经过构造函数建立对象,必须使用 new 运算符。

既然经过构造函数能够建立对象,那么这个对象是哪里来的, new Object()在什么地方执行了?执行的过程以下:

1.当使用了构造函数,而且 new 构造函数(),那么就后台执行了 new Object();
2.将构造函数的做用域给新对象 ,(即 new Object()建立出的对象),而函数体内的 this 就 表明 new Object()出来的对象。
3.执行构造函数内的代码; 
4.返回新对象(后台直接返回)。

带原型的Constructor(构造器)

js中有一个名为prototype的属性。调用js构造器建立一个对象后,新对象就会具备构造器原型的全部属性。经过这种方式,能够建立多个Car对象,并访问相同的原型。

<script type="text/javascript">
        function Car(model,year,miles) {
            this.model = model;
            this.year = year;
            this.miles = miles;
        }
        Car.prototype.run = function () {
            return this.model + " has done " + this.miles + " miles ";

        };
        var Benz = new Car('S350',2010,20000);
        var Ford = new Car('Ford',2012,12000);

        console.log(Benz.run());//"S350 has done 20000 miles "
        console.log(Ford.run());
    </script>

如今run()的单一实例就可以在全部Car对象之间共享。

相关文章
相关标签/搜索