1.原型链继承
1.1 原理:将父类的实例添加到子类的原型上
1.2 缺点:父类新增原型方法/原型属性,子类都可以访问到,父类一变子类都会改变
function Person (name) {
this.name = name;
};
Person.prototype.getName = function () { //对原型进行扩展
return this.name;
};
function Parent (age) {
this.age = age;
};
Parent.prototype = new Person('老明');
Parent.prototype.getAge = function () {
return this.age;
};
var result = new Parent(22);
2.构造继承
2.1 原理:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
2.2 缺点:方法都在构造函数中定义, 只能继承父类的实例属性和方法,不能继承原型属性/方法,无法实现函数复用,每个子类都有父类实例函数的副本,影响性能
function Person (name) {
this.name = name;
this.friends = ['小李','小红'];
this.getName = function () {
return this.name;
}
};
// Person.prototype.geSex = function () { //对原型进行扩展的方法就无法复用了
// console.log("男");
// };
function Parent = (age) {
Person.call(this,'老明'); //这一句是核心关键
//这样就会在新parent对象上执行Person构造函数中定义的所有对象初始化代码,
// 结果parent的每个实例都会具有自己的friends属性的副本
this.age = age;
};
var result = new Parent(23);
console.log(result.name); //老明
console.log(result.friends); //["小李", "小红"] console.log(result.getName()); //老明 console.log(result.age); //23 console.log(result.getSex()); //这个会报错,调用不到父原型上面扩展的方法
3.组合继承
所有的实例都能拥有自己的属性,并且可以使用相同的方法,组合继承避免了原型链和借用构造函数的缺陷,结合了两个的优点,是最常用的继承方式
3.1.原理:通过调用父类构造,继承父类的属性并保留传参的优点,再通过将父类实例作为子类原型,实现函数复用
function Person (name) {
this.name = name;
this.friends = ['小李','小红'];
};
Person.prototype.getName = function () {
return this.name;
};
function Parent (age) {
Person.call(this,'老明'); //这一步很关键
this.age = age;
};
Parent.prototype = new Person('老明') //这一步也很关键
4.寄生组合继承
4.1 原理: 通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实例方法/属性,避免了组合继承的缺点
function Person(name) {
this.name = name;
this.friends = ['aa','bb'];
}
Person.prototype.getName = function () {
return this.name;
};
function Parent(age) {
Person.call(this,"cc");
this.age = age;
}
(function () {
var Super = function () {}; // 创建一个没有实例方法的类
Super.prototype = Person.prototype;
Parent.prototype = new Super(); //将实例作为子类的原型
})();
var result = new Parent(23);
网友评论