忘记版-ES3、ES5实现继承的方式

101

忘记版-ES3、ES5实现继承的方式

寄生组合式继承

构造函数继承:在子类构造函数中调用执行父类构造函数实现所有属性方法独享,但无法做到属性、方法共享;
原型链继承:子类原型指向父类的实例从而实现原型共享;
寄生继承:因为组合式继承调用了两次父类(构造函数继承和原型链继承组合),所以有了寄生继承,实现跟工厂模式差不多,就是调用一个仅用于封装继承过程的函数 也就是下面的Object.create

JS代码

// 父级
function Person(name) {
    this.name = name;
}
Person.prototype.sayName = function() {
    console.log('person name:', this.name);
}

// 子级
function Student(name, personName) {
    Person.call(this, personName);
    this.name = name;
}

// ES5之后才支持Object.create,所以在ES3里可以自己写个模拟方法
if(!Object.create){
	Object.create = function(proto){
		function F(){}
		F.prototype = proto;
		return new F();
	}
}

// 错误写法
// 1.错 这种写法导致Student新增的属性在Person里也会存在
// Student.prototype = Person.prototype;

// 2.错 new Person()会得到Person的实例,实例指向了Person.prototype并且调用了构造函数,这样也算实现了继承,但就因为调用了构造函数,这样也是会有问题的,比如new Person()时候的name传什么呢?哈哈传任何东西都很奇怪,Student只是一个类还没有实例化呢,这里只是为了继承,就要调用构造函数且创造实例是不是很奇怪
// Student.prototype = new Person();

// 相对理想的写法
// Object.create创建了空对象,且对象原型指向了Person.prototype,这样既保证了继承Person.prototype上的方法,且Student.prototype有自己的空对象,自己的修改不会影响到原型链上的属性

Student.prototype = Object.create(Person.prototype);
Student.prototype.sayName = function() {
    console.log('student name:', this.name);
}

Student.prototype.constructor = Person;

var person = new Person('person');
person.sayName();    // person name: person

var student = new Student('student', 'person');
student.sayName();    // student name: student

OK,已完成一道比较经典的继承理论代码。

End