Javascript定义类(class)的三种方法
文章目录
在面向对象编程中,类(class)是对象(object)的模板,定义了同一组对象(又称”实例”)共有的属性和方法。
Javascript语言不支持”类”,但是可以用一些变通的方法,模拟出”类”。
1、构造函数法
第一种是经典方法,它用构造函数模拟”类”,在其内部用this关键字指代实例对象。
1 2 3 |
function Dog() {
this.name = "旺财";
} |
生成实例的时候,使用new关键字。
1 2 |
var dog = new Dog(); console.log(dog.name); // 旺财 |
类的属性和方法,还可以定义在构造函数的prototype对象之上。
1 2 3 |
Dog.prototype.wow = function(){
console.log("汪~汪~汪!");
} |
关于这种方法的详细介绍,请看《Javascript 面向对象编程》,这里就不多说了。
它的主要缺点是,比较复杂,用到了this和prototype,编写和阅读都很费力。
2、Object.create()法
在ECM5中,加入一个新的方法 Object.create(),用这个方法,”类”就是一个对象,不是函数。
1 2 3 4 5 6 |
var Dog = {
this.name = "旺财";
wow: function() {
console.log("汪~汪~汪!");
}
} |
然后,直接用Object.create()生成实例,不需要用到new。
1 2 3 |
var dog = Object.create(Dog); console.log(dog.name); // 旺财 dog.wow(); // 汪~汪~汪! |
这种方法不能实现私有属性和私有方法,实例对象之间也不能共享数据。
3、BlackScript 法
荷兰程序员Gabor de Mooij提出了一种比Object.create()更好的新方法。
事实上就是用一个对象模拟类,在这个类里,定义一个构造函数 createNew() 用来生成实例。
1 2 3 4 5 |
var Dog = {
createNew: function(){
//some code
}
} |
然后,在 createNew() 里面,定义一个实例对象,把这个实例对象作为返回值
1 2 3 4 5 6 7 8 9 10 |
var Dog = {
createNew: function(){
var dog = {};
dog.name = "旺财";
dog.wow = function() {
console.log("汪~汪~汪!");
}
return dog;
}
} |
使用方法
1 2 |
var dog1 = Dog.createNew(); dog1.wow(); // 汪~汪~汪! |
这种方法简单易学,可以实现OOP的特性,继承、私有属性和方法、数据共享。
继承
比如让 Dog 继承 Animal,只要在 Dog的 createNew()方法中,调用后者的createNew()方法即可。
1 2 3 4 5 6 7 8 9 |
var Animal = {
createNew: function(){
var animal = {};
animal.sleep = function(){
console.log("睡懒觉");
};
return animal;
}
}; |
然后,在 Dog 的 createNew() 方法中,调用 Animal 的 createNew() 方法。
1 2 3 4 5 6 7 8 9 10 |
var Dog = {
createNew: function(){
var dog = Animal.createNew();
dog.name = "旺财";
dog.wow = function() {
console.log("汪~汪~汪!");
}
return dog;
}
} |
这样得到的 Dog 实例,就会同时继承 Dog 类和Animal类。
1 2 3 |
var dog1 = Dog.createNew(); dog1.sleep() // 睡懒觉 dog1.wow() // 汪~汪~汪! |
私有属性和方法
在 createNew() 方法中,只要不是定义在 dog 对象上的方法和属性,都是私有的。
1 2 3 4 5 6 7 8 9 10 11 |
var Dog = {
createNew: function(){
var dog = {};
var sound = "汪汪汪";
dog.name = "旺财";
dog.wow = function() {
console.log(sound);
}
return dog;
}
} |
上例的内部变量 sound,外部无法读取,只有通过 dog 的公有方法 wow() 来读取。
1 2 3 4 |
var dog1 = Dog.createNew(); dog1.name // 旺财 dog1.sound // undefined dog1.wow() // 汪汪汪 |
数据共享
有时候,我们需要所有实例对象,能够读写同一项内部数据。
这个时候,只要把这个内部数据,封装在类对象的里面、createNew()方法的外面即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var Dog = {
sound: "汪汪汪",
createNew: function(){
var dog = {};
dog.name = "旺财";
dog.sound = function() {
console.log(Dog.sound);
}
dog.changSound = function(para){
Dog.sound = para
}
return dog;
}
}; |
生成两个实例
1 2 3 4 |
var dog1 = Dog.createNew(); var dog2 = Dog.createNew(); dog1.sound(); // 汪汪汪 dog2.sound(); // 汪汪汪 |
这时,如果有一个实例对象,修改了共享的数据,另一个实例对象也会受到影响。
1 2 |
dog2.changSound("呱呱呱");
dog1.sound(); // 呱呱呱 |
本文转载引用自 Javascript定义类(class)的三种方法
文章作者 ZHIKING
上次更新 2017-03-23