原型链继承(实例.prototype = new 原型)
该方法有一个弊端:1)实例属性无法传给原型;2)多个实例共用原型的构造方法,导致引用数据类型共用
function Person() {
this.name = 'sss';
this.age = 12;
this.friends = ['aaa', 'bbb', 'ccc'];
this.say = function() {
console.log(this.name + this.age);
};
this.social = function() {
console.log('-----friends', this.friends);
}
}
function Child() {
this.name = 'fff';
}
Child.prototype = new Person(); // 将Child继承父类Person
var person = new Person();
var child = new Child();
person.say(); // sss12
child.say(); // fff12 // 继承父类age属性
child.name = 'change';
child.age = 15;
child.friends.push('ddd');
var child2 = new Child(); // 另一个实例
child.say(); // change15; 子类的属性覆盖父类
child2.say();
child.social(); //['aaa','bbb','ccc','ddd']
child2.social(); // 多个实例共享原型的一个构造方法,导致引用类型变量共用,输出['aaa','bbb','ccc','ddd']
person.say();
当继承的函数被调用时,this指向的是继承的函数,而非继承的原型的函数。当在继承的对象中查找某个属性的时候,js不仅会在当前属性查找,还会沿着原型链一直查找,当要查找的是不存在的属性时,甚至会遍历原型链上所有对象,影响性能。
借用构造函数
function Colors() {
this.color = ['red', 'green', 'yellow'];
}
function Child() {
Colors.call(this); // 这里把原型构造函数的this指向实例,实现继承
}
var child = new Child();
child.color.push('black');
console.log(child.color); // ['red','green','yellow', 'black']
var child2 = new Child();
console.log(child2.color); // 每个实例有自己的构造方法,['red','green','yellow']
组合继承:利用原型链实现实例对父类的继承,通过借用构造函数实现父类对实例属性的继承
代码就是以上两种的组合;
如何用ES6实现类和继承
注意:ES6的class可以实现类的封装,但是本质还是原型链,只是语法糖。
class Parents {
// 构造属性
constructor(name) {
this.name = name;
}
// 方法
static sayHello() {
console.log('hello');
}
sayName() {
console.log(this.name);
return this.name;
}
}
// 子类继承父类
class Child extends Parents {
constructor(name, age) {
super(name); // 覆盖父类的属性
this.age = age;
}
sayAge() {
console.log(this.age);
}
}
var parent = new Parents('Wang');
var child = new Child('Li', 15);
console.log('parent: ', parent); // parent: Parent {name: "Parent"}
Parents.sayHello(); // 用static修饰的静态方法不能被实例调用,只能原型的方式调用
parent.sayName(); // Wang
console.log('child: ', child); // child: Child {name: "Child", age: 15}
Child.sayHello(); // hello
child.sayName(); // my name is Child
child.sayAge(); // my age is 18