工厂函数、构造函数、原型、动态原型总结
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; } }