1.基于原型链的继承
基本原理是:将父类的实例赋值给子类的原型。
// 父类
function Staff() {
this.company = "huang";
this.list = [];
}
console.dir(Staff);
// 父类的原型
Staff.prototype.getComName = function () {
return this.company;
};
console.log(Staff.prototype.__proto__ === Object.prototype);
// 子类
function Coder(name, skill) {
this.name = name;
this.skill = skill;
}
// 继承 Staff
Coder.prototype = new Staff();
// 因为子类原型的指向已经变了,所以需要把子类原型的contructor指向子类本身
Coder.prototype.constructor = Coder;
// 给子类原型添加属性
Coder.prototype.getInfo = function () {
return {
name: this.name,
skill: this.skill,
};
};
let coder = new Coder("小明", "javascript");
console.log(coder.getInfo()); // {name: '小明', skill: 'javascript'}
console.log(coder.getComName()); // 'huang' 调用的父类原型链上的的方法
这种继承方式的缺点:
子类的实例可以访问父类的私有属性,子类的实例还可以更改该属性,这样不安全。
2. 基于class
class Parent {
constructor(name) {
this.name = name;
}
static say() {
return "hello";
}
}
class Child extends Parent {
constructor(name, age) {
super(name);
this.age = age;
}
}
let Child1 = new Child("huang", "22");
console.log(Child.say());// hello
console.log(Child1);
- class 只能通过 new 来调用,而构造函数则可以直接调用;
- 子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这是因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,如果不调用 super 方法,子类就得不到 this 对象。
- 子类可以继承父类的静态方法。