1、原型链继承:
function Father(){
this.arr=[2,3,4];
}
function Son(){};
Son.prototype = new Father();
var son1=new Son();
console.log(son1.arr)
son1.arr.push(4);
console.log(son1.arr)
var son2=new Son();
console.log(son2.arr);
//[ 2, 3, 4 ]
//[ 2, 3, 4, 4 ]
//[ 2, 3, 4, 4 ]
缺点:①原型链中引用类型的属性会被所有实例共享,所有实例对象使用同一份数据,会相互影响。②无法传参。
2、借用构造函数继承。
function Father(){
this.arr = [2,3,4];
}
function Son(){
Father.call(this);
//上面的代码等同于
// (function(){
// this.arr = [2,3,4]
// }).call(this)
}
var son1 = new Son();
console.log(son1.arr);
var son2 = new Son();
son2.arr.push(4);
console.log(son2.arr);
console.log(son1.arr);
//[ 2, 3, 4 ]
//[ 2, 3, 4, 4 ]
//[ 2, 3, 4 ]
优点:①解决了传参问题。
function Father(name) {
this.name = name;
}
function Son(name) {
Father.call(this, name);
}
let son1 = new Son("son1");
console.log(son1.name); // son1
let son2 = new Son("son2");
console.log(son2.name); // son2
缺点:通过构造函数实现,每个实例都创建了一份副本,构造函数自身的问题——破坏了复用性。
3、组合继承
function Father(name) {
this.name = name;
this.arr = [1,2,3];
}
Father.prototype.getName = function() {
console.log(this.name);
}
function Son(name, age) {
Father.call(this, name);
this.age = age;
}
Son.prototype = new Father();
Son.prototype.constructor = Son;
Son.prototype.getAge = function() {
console.log(this.age);
}
let son1 = new Son("son1", 23);
son1.arr.push(4);
console.log(son1.arr); //1,2,3,4
son1.getName(); //son1
son1.getAge(); //23
let son2 = new Son("son2", 24);
console.log(son2.arr); //1,2,3
son1.getName(); //son2
son1.getAge(); //24
解析
借用构造函数部分:
· Father.call(this, name) —— name来自Father
· this.age = age; Son.prototype.constructor = Son —— age来自Son
原型链部分:
· Father.prototype.getName —— getName方法来自Father.prototype
· Son.prototype.getAge —— getAge来自Son.prototype