关于JavaScript编写类的方式,总结一下JavaScript编写类的几种写法以及这几种写法的优缺点。
构造函数方式
基本语法:
1 |
|
1 |
|
测试Person类
1 |
|
这种方式的优点是:可以根据参数来构造不同的对象实例 ,每个对象的属性一般是不相同的,缺点是构造每个实例对象时,方法不能共享,Person类里面定义的那些方法,p1对象有一份,p2也有一份,那么在内存中就得开辟两块内存空间来分别存储p1的方法和p2的方法,这样就造成了内存的浪费。对于一个类的不同实例对象,这些对象的属性一般是不相同的,但是方法是相同的,所以节约内存的做法就是把方法放到内存的一块区域中存放,然后每个实例对象都从这块内存中取出方法。
原型方式
需要说明的是,使用原型方式编写JavaScript类是无法给类添加私有属性和私有方法的,使用原型方式添加的属性和方法都是public的。
写法一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*定义一个Person类*/
function Person(_name,_age,_weight,_height){
this.init(_name,_age,_weight,_height);
}
/*使用原型的方式定义Person类的public属性:name,age,weight,height,使用原型的方式添加的属性都是public的*/
Person.prototype.name;
Person.prototype.age;
Person.prototype.weight;
Person.prototype.height;
/*使用原型的方式给Person类添加public方法,使用原型的方式添加的方法都是public的*/
/*使用原型的方式给Person类添加init方法*/
Person.prototype.init = function(_name,_age,_weight,_height) {
if(_name != undefined && _age!=undefined && _weight!=undefined && _height!=undefined){
this.name = _name;
this.age = _age;
this.weight=_weight;
this.height=_height;
document.writeln("this.name="+this.name+",this.age="+this.age+",this.weight="+this.weight+",this.height="+this.height);
}
}
/*使用原型的方式给Person类添加show方法*/
Person.prototype.show = function(){
document.writeln("show method");
}测试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18document.write("<pre>");
var p1 = new Person("孤傲苍狼",24,115,160);
var p2 = new Person("白虎神皇",25,120,170);
var p3 = new Person();
p3.init("玄天邪帝",26,130,180);//调用public方法init初始化p3对象
document.writeln("p1 instanceof Person的结果是:"+(p1 instanceof Person));//p1是Person类的实例,结果是true
document.writeln("p2 instanceof Person的结果是:"+(p2 instanceof Person));//p2是Person类的实例,结果是true
document.writeln("p3 instanceof Person的结果是:"+(p3 instanceof Person));//p3是Person类的实例,结果是true
//当==两边的内容是对象或者是对象的函数属性时,则比较内存地址是否相等
document.writeln("当==两边的内容是对象或者是对象的函数属性时,则比较内存地址是否相等");
document.writeln("比较p1和p2这两个对象的show方法的内存地址是否一样:p1.show == p2.show的结果是:"+(p1.show == p2.show));//true
document.writeln("p1.show == p2.show的结果是:"+(p1.show == p2.show)+",这证明p1对象和p2对象共享一个show方法,在内存中show方法的代码只有一份,存放在内存的一块区域");//true
document.writeln("p1.name="+p1.name+",p1.age="+p1.age+",p1.weight="+p1.weight+",p1.height="+p1.height);//访问公有属性,这是可以正常访问的
document.writeln("p2.name="+p2.name+",p2.age="+p2.age+",p2.weight="+p2.weight+",p2.height="+p2.height);//访问公有属性,这是可以正常访问的
p3.name="灭世魔尊";//为公共属性重新赋值
document.writeln("p3.name="+p3.name);//访问公有属性,这是可以正常访问的
p1.show();//调用类的公共函数,这次允许的
document.write("</pre>");写法二
使用原型方式给类定义public属性和public方法更加优雅的写法,我个人推荐使用这种方式,这种方式看起来比较舒服
1 | /*定义类Person2*/ |
测试代码:
1 |
|
构造函数+原型
构造函数方式和原型方式都有各自的优缺点,因此可以把这两种方式合并起来,用构造函数方式来定义类的属性(public属性,private属性),用原型方式来定义类的方法(public方法)。互补不足,这就有了第三种写法。
1 | /*定义一个Person类*/ |
测试代码:
1 | var p1 = new Person("孤傲苍狼",24,2300); |
第三种方式通过前两种方式的结合,算是达到了一个比较理想的写法了,可以通过传参构造对象实例,对象实例都共享同一份方法不造成内存浪费。第三种方式在开发中用得最多,我本人也是采用这种方式来编写JavaScript类。