一.基于原型链的继承
基本原理是:将父类的实例赋值给子类的原型。
// 父类
function Staff() {
this.company = 'tianchuang';
this.list = [];
}
// 父类的原型
Staff.prototype.getComName = function() {
return this.company;
};
// 子类
function Coder(name, skill) {
this.name = name;
this.skill = skill;
}
// 继承 Staff
Coder.prototype = new Staff();
// 因为子类原型的指向已经变了,所以需要把子类原型的co ntructor指向子类本身
Coder.prototype.constructor = Coder;
// 给子类原型添加属性
Coder.prototype.getInfo = function() {
return {
name: this.name,
skill: this.skill
};
};
let coder = new Coder('小明', 'javascript');
coder.getInfo(); // {name: '小明', skill: 'javascript'}
coder.getComName(); // 'tianchuang'
这种继承方式的缺点:
子类的实例可以访问父类的私有属性,子类的实例还可以更改该属性,这样不安全。
二.基于构造函数的继承
原理:在子类构造函数中,使用call来将子类的this绑定到父类中去
// 父类
function Staff() {
this.company = 'tianchuang';
this.list = [];
}
// 父类的原型
Staff.prototype.getComName = function() {
return this.company;
};
// 子类
function Coder(name, skill) {
Staff.call(this);
this.name = name;
this.skill = skill;
}
let coder = new Coder('xiaoming', 'java');
let coder2 = new Coder('zhaosan', 'c');
coder.getComName(); // Uncaught TypeError: coder.getComName is not a function
coder.list; //[]
coder.list.push(1); //[1]
coder2.list; //[]
三.基于class extend 继承
ES6 中有了类的概念,可以通过 class 声明一个类,通过 extends 关键字来实现继承关系。 class 与 ES5
构造函数的主要区别:
class 只能通过 new 来调用,而构造函数则可以直接调用; class
内部所有定义的方法,都是不可枚举的(non-enumerable)
class Parent {
constructor(name) {
this.name = name;
}
static say() {
return 'hello';
}
}
class Child extends Parent {
constructor(name, age) {
super(name); // 调用父类的 constructor(name)
this.age = age;
}
}
var child1 = new Child('kevin', '18');
console.log(child1);