在ES6还未出现时,我们使用如下方法通过javascript使用类。在下图中函数Person为构造函数,因为要通过它,new出实例,所以一般要首字母大写。

第一种方法:构造函数法

// 1.构造函数法
function Person(name, age, sex) {
    	this.name = name;
    	this.age = age;
    	this.sex = sex;
    	this.say = function() {
    		console.log(`我是${ this.name }`);
    	}
}

zs = new Person('张三', 16, '男');
zs.say();  // 我是张三
console.log(zs.name);  // 张三

优点:通过new出来的每个实例都有一份属于自身的数据。

缺点:在定义函数的时候,内存造成了很大的浪费。例如上例中的say()函数。

第二种方法:原型对象法

// 2.原型对象法
function Person() {}
Person.prototype.say = function() { console.log(`我是${ this.name }`);}; 
Person.prototype.name = '张三';
Person.prototype.age = 16;
Person.prototype.sex = '男';
let zs = new Person('张三', 16, '男');
zs.say();		// 我是张三
console.log(zs.name);		// 张三

优点:共用一个类中的方法,节省了大量的存储空间。

缺点:所有实例共用一份数据,数据赋值和使用比较麻烦。

第三种方法:构造函数法 + 原型对象法

// 3.构造函数法 + 原型对象法。
function Person(name, age, sex) {
	this.name = name;
	this.age = age;
	this.sex = sex;
}
Person.prototype.say = function() { console.log(`我是${ this.name }`); };

该方法结合了上述两种方法的优点,使new出来的实例既不会因为类中的方法而浪费大量的存储空间,也不会让所有的实例都共用一份数据。

类中的属性:

动态共有属性:所有对象(实例)各自持有,且可以通过对象点来直接访问与赋值的属性。在构造函数中用this关键字来动态开辟该属性。

动态私有属性:所有对象(实例)各自持有,但不可以通过对象点来直接访问与赋值的属性。在构造函数中通过声明局部变量来表示该属性。

function Person(name) {
    	var a = 100;            // 动态共有属性
    	this.name = name;       // 动态私有属性
}

静态私有属性:所有对象共用,且不可以通过对象直接点来访问的属性。把构造函数放在一个IIFE表达式中作为返回值,并闭包IIFE中的局部变量。

静态共有属性:所有对象共用,且可以通过对象直接点来访问的属性。

var Person = (function() {
    	var b = '黄帝';                // 静态私有属性
    	return function Person() {
            var a = 100;               // 静态共有属性
            this.setA = function(val) { a = val; };
            this.getA = function() { return a; };
            this.setB = function(val) { b = val; };
            this.getB = function() { return b };
    	};
})();

类的继承:

 下面示例继承了上述Person类:

// 类的继承
function Doctor(name, age, sex, major) {
    	Person.call(this, name, age, sex);    // 继承父类中的数据
    	this.major = major;
}

Doctor.prototype = new Person();        // 继承父类中的方法
Doctor.prototype.constructor = Doctor;  // __proto__属性混乱,找不到它的原型对象
Doctor.prototype.kangbing = function() {
    console.log(this.name + '正在看病');
};

let ml = new Doctor('马六', 22, '男', '口腔科');
console.log(ml.major);		// 口腔科
ml.say();		// 我是马六
ml.kangbing();	// 马六正在看病

我们通过ES5中类的实现原理,可以更好的理解ES6中类的原理和使用。