1,原型链继承
function Parent() {
this.name = 'Parent';
}
function Child() {
this.age = 10;
}
Child.prototype = new Parent(); // Child的原型指向Parent的一个实例
var child = new Child();
console.log(child.name); // 输出: Parent
优点 简单明了,容易实现,在父类新增原型属性和方法,子类都能访问到。
缺点 所有的实例都指向同一个引用地址,修改一个原型上的属性或方法,其他都会改变。不能向超类型的构造函数传递参数
2,借用构造函数继承
function Parent(name) {
this.name = name;
}
function Child(name, age) {
Parent.call(this, name); // 借用Parent的构造函数
this.age = age;
}
var child = new Child('Child', 10);
console.log(child.name); // 输出: Child
优点:保证每个实例都有自己的属性。可向父对象的构造函数传递参数。
缺点:方法不能被复用(每个对象实例都会创建一个新的方法)。
3,组合继承
function Parent(name) {
this.name = name;
}
function Child(name, age) {
Parent.call(this, name); // 继承属性
this.age = age;
}
Child.prototype = new Parent(); // 继承方法
var child = new Child('Child', 10);
console.log(child.name); // 输出: Child
结合了上述两种方法的优点,既可以在子类实例上共享方法,又可以保证每个实例都有自己的属性。
4,寄生组合式继承
function Parent(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
Parent.prototype.sayName = function() {
console.log(this.name);
};
function Child(name, age) {
Parent.call(this, name); // 继承父类的属性
this.age = age;
}
// 寄生组合式继承的核心
function inheritPrototype(child, parent) {
var prototype = Object.create(parent.prototype); // 创建一个中间对象,其原型为父类的原型
prototype.constructor = child; // 此时constructor为Parent,修正中间对象的constructor属性为Child
child.prototype = prototype; // 将子类的原型设置为中间对象
}
inheritPrototype(Child, Parent);
//Object.create可替换为此object函数避免es5之前不支持的情况
function object(o) {
function F(){}
F.prototype = o
return new F()
}
var child1 = new Child('Tom', 5);
child1.colors.push('black');
console.log(child1.name); // 输出 "Tom"
console.log(child1.age); // 输出 5
console.log(child1.colors); // 输出 ["red", "blue", "green", "black"]
child1.sayName(); // 输出 "Tom"
var child2 = new Child('Jerry', 4);
console.log(child2.name); // 输出 "Jerry"
console.log(child2.age); // 输出 4
console.log(child2.colors); // 输出 ["red", "blue", "green"]
child2.sayName(); // 输出 "Jerry"
寄生组合式继承通过创建一个中间对象来继承父类的原型,从而避免了组合式继承中需要调用父类构造函数两次的问题。这种方式有效地减少了不必要的开销,提高了继承的效率。
5,class继承
// 定义父类 Parent
class Parent {
constructor(name) {
this.name = name;
}
// 父类的方法
sayHello() {
console.log(`Hello, my name is ${this.name} and I am a Parent.`);
}
}
// 定义子类 Child,继承自 Parent
class Child extends Parent {
constructor(name, age) {
// 调用父类的constructor
super(name);
// 定义子类特有的属性
this.age = age;
}
// 子类重写父类的方法
sayHello() {
// 调用父类的方法(如果需要的话)
// super.sayHello();
// 定义子类特有的行为
console.log(`Hello, my name is ${this.name} and I am a Child. I am ${this.age} years old.`);
}
// 子类特有的方法
describeAge() {
console.log(`I am ${this.age} years old.`);
}
}
// 使用示例
const parentInstance = new Parent('John');
parentInstance.sayHello(); // 输出: Hello, my name is John and I am a Parent.
const childInstance = new Child('Jane', 10);
childInstance.sayHello(); // 输出: Hello, my name is Jane and I am a Child. I am 10 years old.
childInstance.describeAge(); // 输出: I am 10 years old.