原始方式
1 2 3 4 5 6 7 8 9
| var aCar=new Object(); aCar.color="red"; aCar.door="8"; aCar.year="2016"; aCar.showCar=function () { console.log(aCar.door); }; aCar.showCar();
|
当创建多个实例对象时,上面的aCar不能充当constructor(构造器)
工厂方式
通过下面的方法,我们可以很容易出的创造多个实例对象
为函数传递参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| console.log(this.door); }*/ function cCar(color, door, year) { var thisCar=new Object(); thisCar.color=color; thisCar.door=door; thisCar.year=year; thisCar.showCar=function () { console.log(this.door); }; return thisCar; } var xc=cCar("blue","6","2017"); xc.showCar();
|
采用这种方式必须创建对象的方法,每次调用cCar(),都要创建showcar()
所以我们可以在工厂函数外定义对象的方法,然后在工厂函数内通过属性指向该方法
构造函数方式
1 2 3 4 5 6 7 8
| function bCar() { this.color="blue"; this.door="4"; this.year="2017"; this.miles="10000"; } var xb=new bCar(); console.log(xb.door);
|
构造函数方式看起来很像工厂方式
区别:构造函数内没有创建对象,而是使用了this关键字
使用new运算符时,只有使用this才能访问该对象
上面2者每次调用时都会创建独立的函数,因此↓
原型方式
利用对象的prototype属性,可以看成我们创建了新对象所依赖的原型
所有属性和方法直接赋予prototype属性
1 2 3 4 5 6 7 8 9 10 11 12
| function dCar() { } dCar.prototype.color="black"; dCar.prototype.door="10"; dCar.prototype.year="2010"; dCar.prototype.showColor=function () { console.log(this.color); }; var xd=new dCar(); xd.showColor();
|
上面的方式中,通过dCar的prototype属性添加属性去定义dCar对象的属性
当调用dCar()时,原型的所有属性被立即赋予要创建的对象
味着所有实例存放的都是指向showColor()的指针
原型方式的问题
不能通过给构造函数传递参数来初始化属性的值,必须在创建对象后才能改变属性的默认值
必须在创建对象后才能改变属性的默认值
1 2 3 4
| dCar.prototype.dd=["1","2"]; xd.dd.push("3"); var xd1=new dCar(); console.log(xd1.dd);
|
上面的问题是属性dd是指向[]对象的指针↓
混合的构造函数/原型方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function eCar(color, door, year) { this.color=color; this.door=door; this.year=year; this.dd=["1","2"] } eCar.prototype.showColor=function () { console.log(this.color) }; var xe1=new eCar("red",4,2011), xe2=new eCar("blue",3,2025); xe1.dd.push("3"); console.log(xe1.dd); console.log(xe2.dd);
|
构造函数内创建对象的属性,外面创建对象的方法
动态原型方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| function Car(sColor,iDoors,iMpg) { this.color = sColor; this.doors = iDoors; this.mpg = iMpg; this.drivers = new Array("Mike","John"); if (typeof Car._initialized == "undefined") { Car.prototype.showColor = function() { alert(this.color); }; Car._initialized = true; } }
|
直到检查 typeof Car._initialized 是否等于 “undefined” 之前,这个构造函数都未发生变化。
这行代码是动态原型方法中最重要的部分。
如果这个值未定义,构造函数将用原型方式继续定义对象的方法,然后把 Car._initialized 设置为 true。
如果这个值定义了(它的值为 true 时,typeof 的值为 Boolean),那么就不再创建该方法。
简而言之,该方法使用标志(_initialized)来判断是否已给原型赋予了任何方法。
该方法只创建并赋值一次,传统的 OOP 开发者会高兴地发现,这段代码看起来更像其他语言中的类定义了。
ECMAScript 定义类或对象