工厂模式
function createObject(name,age,job){
    var obj = new Object();
    obj.name =name;
    obj.age = age;
    obj.job = job;
    return obj;
}
注意
- 使用工厂模式创建对象对象的时候,不需要使用new操作符,直接当成普通函数调用就行
 - 工厂模式创建对象最后要将obj返回。
 
缺点:无法解决对象识别的问题。即无法知道一个对象的类型。
构造器(构造函数)模式
function CreateObject (name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
}
注意
- 使用构造函数创建对象的时候,需要使用new操作符。
 - 构造函数内部不需要有对象返回。
 - 构造函数不需要显式的返回一个值,在使用new来创建一个对象的时候,如果return的是一个非对象,则会忽略返回值,如果return的是一个对象,则会返回这个对象
 
使用构造函数创建对象的时候发生的事情:
- 在内存中开辟一个空间,这个空间用于存储创建的新的对象
 - 将this指向这个空间
 - 将新生成的这个对象的
__proto__指向构造函数的prototype.这一步是建立对象和原型直接的对应关系 - 执行构造函数中的代码(为这个对象添加属性和方法)
 - 将新对象返回。(将this返回)
 
缺点:每个方法都要在实例对象上重新创建一次,因此,不同实例上的同名函数是不相等的。这样极大的浪费了存储空间。
原型模式
function Person (){}
Person.prototype.name = 'a';
Person.prototype.age = b;
Person.prototype.job = 'c';
注意
- 构造函数中有一个prototype属性,指向这个构造函数的原型对象
 - 原型对象中有一个constructor属性,指向这个原型对象对应的构造函数
 - 由构造函数实例化出来的实例对象中有一个proto属性,同样也指向实例对象所对应的构造函数的原型对象。
 
缺点
- 使用原型模式创建对象的时候,如果存在有引用类型的属性,如果生成了两个实例对象,其中一个实例对象改变了这个引用类型的属性,则另外一个实例对象的该属性的值也会改变。
 
组合使用构造函数模式和原型模式——-最优模式
//构造函数模式用于定义实例属性
function Person (name,age,job){
    this.name = name;
    this.job = job;
    this.age = age;
}
//原型模式用户定义方法和共享属性。
Person.prototype ={
    constructor:Person,
    sayName:function(){
        console.log(this.name);
    }
}