美文网首页
我对工厂和构造函数方式创建对象的理解

我对工厂和构造函数方式创建对象的理解

作者: Uniquelah | 来源:发表于2017-04-05 13:38 被阅读41次
    为什么要使用工厂模式和构造函数方式创建对象?

    虽然Object构造函数(var obj = new Object();)或者字面量(var person={})可以创建单个对象,但是,他有一个明显的缺点,那就是:重复造轮子,产生大量的重复性代码,为了解决这个问题,我们就开始使用工厂模式和构造函数模式。

    什么是工厂模式 它有什么优缺点?

    顾名思义,工厂模式就是像工厂一样来创建对象。但这样的解释似乎有点欠妥,高大上一点,工厂模式其实是软件领域中一种广为人知的一种设计模式,这种模式抽象了创建具体对象的过程。开发人员发明了一种函数,用函数来大量创建对象的方法;

    下面是工厂模式创建对象的方法:

    <pre>
    <script>
    function creatPerson(name,age,sex){
    // var person = {};
    // person.name = name;
    // person.age = age;
    // person.sex = sex;
    // return person;
    return{
    name:name,
    age:age,
    sex:sex
    }
    }
    var person1 = creatPerson("李四",18,"男")
    var person2 = creatPerson("李四z",28,"男")
    var person3 = creatPerson("李四zzz",30,"男")
    console.log(person1);
    console.log(person2);
    console.log(person3);
    </script>
    </pre>

    虽然工厂模式可以创建多个相似的对象,但是却没有解决对象的识别问题(不知道这个对象的类型)。

    什么是构造函数模式,它和工厂模式比较有哪些好处?它自身又有那些缺点?

    1.实例如下:

    <pre>
    <script>
    function Person(name,age){
    this.name = name;
    this.age = age;

    }
    
    var p = new Person("张三","10s岁");
    var p2 = new Person("李四","16岁");
    
    console.log(p);     
    console.log(p2);
    // console.log(p instanceof Object);
    

    </script>
    </pre>

    这个例子中,Person()函数取代了person()函数;睁大你的眼睛,构造函数创建对象的函数名Person()明显是开头大写,这是构造函数的惯例,为了区分和普通函数的区别,因为构造函数也是函数,只不过可以创建对象而已。

    要创建Person()的新实例,必须使用new,即和使用var person1 = new Person()差不多,实际上会经历一些步骤:

    1. 创建一个新的对象;
    2. 将构造函数作用域赋给新的对象(即this指向新对象);
    3. 执行构造函数里面的代码;
    4. 返回新的对象。
    构造函数和普通函数的区别在哪?

    1.构造函数和普通函数唯一的区别是他们的调用方式不同。
    2.任何函数只要通过new来调用,那它就可以作为构造函数,而任何函数,如果不通过new操作符来调用,他就是普通的函数。

    实例如下:

    <pre>
    //当做构造函数来使用
    var person1 = new CreatePerson('张三',18,'男');
    person1.sex(); //'男'

    //构造函数当做普通函数使用
    CreatePerson('张三',18,'男')
    window.sex();//'男'
    </pre>

    构造函数有哪些不足之处?

    我们可以参照上面的构造函数的第一个实例,可以得出这种方式创建函数实例创建的对象都包含一个不同的Function实例,所以,不同实例上的同名函数是不相等的,证明如下:

    <pre>console.log(person1.sex == person2.sex);//false</pre>

    2.因此以上的写法可以这样简化:

    <pre>function CreatePerson(name,age,sex){
    this.name = name;
    this.age = age;
    this.sex = sex;
    }
    function sexes(){
    console.log(this.sex);
    }
    var person1 = new CreatePerson('张三',18,'男');
    var person2 = new CreatePerson('李四',18,'男')</pre>

    这个时候的person1.sex和person2.sex就是相等的.

    我们把函数放在构造函数的外面作为全局函数,因此person1和person2对象就共享了在全局作用域中定义的同一个sexes函数。但是问题又来了:在全局作用域中定义的函数实际上只能被某个对象调用,这让该全局作用域有点名不副实。更让然无法接受的是:如果对象需要定义很多方法,那么就要定义很多个全局函数,那么我们这个自定义的引用类型就丝毫没有封装性可言了。因此我们需要另一种高大上的模式,——原型模式(prototype)

    相关文章

      网友评论

          本文标题:我对工厂和构造函数方式创建对象的理解

          本文链接:https://www.haomeiwen.com/subject/xhitattx.html