工厂函数、构造函数、原型、动态原型总结

 

Talk is cheap,show U the code!!~~~

 

//基本工厂函数
function createCar(color,doors){
    var oTempCar = new Object;
    oTempCar.color=color;
    oTempCar.doors=doors;
    oTempCar.showColor=function(){
        console.log(this.color);
    };
    return oTempCar;
}
var oCar1=createCar('red','3'),
    oCar2=createCar('blue','4');
/*不好,一是不好看,比如创建对象时,竟然没有牛(new)!
 二是,用这种方式,必须创建对象的方法,即每次调用createCar,都要创建新函数showCar,意味着每个对象都有自己的
 showCar版本,而事实上是,每个对象都共享了同一个函数,太浪费
*/



//升级版的 工厂函数
var showColor=function(){
    console.log(this.color);
};
function createCar(color,doors){
    var oTempCar = new Object;
    oTempCar.color=color;
    oTempCar.doors=doors;
    oTempCar.showColor=showColor;
    return oTempCar;
}
var oCar1=createCar('red','3'),
    oCar2=createCar('blue','4');



/*
* 这种方式,将对象函数定义在外部,虽然解决了函数重复创建函数对象的问题,但还是显得不太正规(没有牛啊!)
* */


//构造函数
function Car(color,doors){
    this.color=color;
    this.doors=doors;
    this.showColor=function(){
        console.log(this.color);
    };
}
var oCar1=new Car('red','3'),
    oCar2=new Car('blue','4');

/*
    这就看起来比较正规了,不过。就像工厂函数,构造函数回重复生成函数,为每个对象都创建独立的函数版本,
    又不过,与工厂函数相似,也可以用外部函数重写够着函数。
* */


//原型方式
function Car(color,doors){

}
Car.prototype.color='red';
Car.prototype.doors=3;
Car.prototype.showColor=function(){
    console.log(this.color);
};

var oCar1=new Car(),
    oCar2=new Car();

/*
* 该方式利用了对象的 prototype属性,在这段代码中,通过给Car的prototype属性添加属性去定义Car的属性(好吧,咱承认,头晕了!!)
* 当调用new Car()时,原型的所有属性,都被立即赋予所要创建的对象,意味着所有Car实例春风·存放的都是指向showCar函数的子镇。
* 从语义上将,所有属性看起来都属于一个对象,因此解决了前连个方式存在的问题。
*
* */



/*
*持外。还能使用instanceof 检查给定变量指向对象的类型,比如:
 */
console.log(oCar1 instanceof Car);  //  true

/*
* 但是,这样不好,一个空函数挂在外面,是咋回事呢??
* 但真正出现的问题是,属性指向的是对象,而不是函数的,函数共享是没有任何问题的,但对象去很少是被多个实例共享的,比如,
* */

function Car(color,doors){

}
Car.prototype.color='red';
Car.prototype.doors=3;
Car.prototype.drivers= new Array('Mike','Sue');
Car.prototype.showColor=function(){
    console.log(this.color);
};

var oCar1=new Car(),
    oCar2=new Car();

oCar1.drivers.push('George');

console.log(oCar1.drivers);   //[ 'Mike', 'Sue', 'George' ]
console.log(oCar2.drivers);   //[ 'Mike', 'Sue', 'George' ]

/*
* 看不,这里就出现了混乱!!
* */


//混合的构造函数 和 原型方式

/*
* 即用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)
* 其结果就是,所有函数都只创建一次,而每个对象都有自己的对象属性实例,例如:
* */

//构造函数
function Car(color,doors){
    this.color=color;
    this.doors=doors;
    this.drivers=new Array('Mike','Sue');
}

//原型方式
Car.prototype.showColor=function(){
    console.log(this.color);
}

var oCar1=new Car('red','3'),
    oCar2=new Car('blue','4');

oCar1.drivers.push('George');

console.log(oCar1.drivers);   //[ 'Mike', 'Sue', 'George' ]
console.log(oCar2.drivers);   //[ 'Mike', 'Sue' ]

/*
* 这里因为使用了原型方式,所以仍然能利用instanceof 判断对象类型,
* 但是,这种做法不和逻辑,因为这要在构造函数内部找属性,在其外部找方法
* */


//动态原型方法
/*
* 基本思想,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义,比如:
* */
function Car(color,doors){
    this.color=color;
    this.doors=doors;
    this.drivers=new Array('Mike','Sue');
    if(typeof Car._initialized == 'undefined'){  //保证showColor方法只创建并赋值一次
        Car.prototype.showColor=function(){
            console.log(this.color);
        };
        Car._initialized=true;
    }
}

 

posted @ 2017-05-06 16:59  快乐的咸鱼  阅读(629)  评论(0编辑  收藏  举报