JavaScript定义对象和类的几种方式

原始方式

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);
};
/*var xa=new aCar();*/
aCar.showCar();

当创建多个实例对象时,上面的aCar不能充当constructor(构造器)

工厂方式

通过下面的方法,我们可以很容易出的创造多个实例对象
为函数传递参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*function showcar() {
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);
};
//thisCar.showCar=showCar;
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();//black

上面的方式中,通过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);//["1", "2", "3"]

上面的问题是属性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);//["1", "2", "3"]
console.log(xe2.dd);//["1", "2"]

构造函数内创建对象的属性,外面创建对象的方法

动态原型方法

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 定义类或对象

文章目录
  1. 1. 原始方式
  2. 2. 工厂方式
  3. 3. 构造函数方式
  4. 4. 原型方式
  5. 5. 混合的构造函数/原型方式
  6. 6. 动态原型方法
,