JS继承的几种方式:
一、原型链继承
1. 继承方式:
子类.prototype = new 父类()
2. 特点:
- 可以继承子类构造函数的属性,也可以继承子类的原型对象的属性,继承父类构造函数的属性,也可以继承父类的原型对象的属性
- 子类对象 实例即是自身, 也是父类
3. 缺点:
- 太单一 : 只能单继承 ,不能进行多继承
- 继承之后原型对象上的属性全部是共享的
- 子类不能直接向父类构造函数传递参数
- 不能在继承前给子类原型的属性赋值,会被继承覆盖掉。
Person.prototype.color = "黄";
Person.prototype.job = function () {
return "工作";
};
function Person() {
this.name;
this.sleep = function () {
return "睡觉";
};
}
Child.prototype = new Person(); //核心 让子类的原型 等于 父类的实例对象
Child.prototype.weight="180kg";
function Child() {
this.age = 20;
}
var child = new Child();
var child1 = new Child();
console.log(child, child1);
二、构造继承
1. 继承方式:
直接在子类的内部去写,在内部使用call(this,a,b,c) 或 apply(this,[a,b,c])调用父类构造函数,并返回结果 ,从而实现子类继承父类的属性和方法。call()中的参数是一个序列,apply()中的参数是数组。
2. 特点:
- 可以向父类传参
- 可以实现多继承,继承多个父类
3. 缺点:
- 子类的实例是本身,不是父类
- 构造继承只能继承父类构造函数的属性和方法 不能继承父类的原型对象的属性和方法
//父类
Animail.prototype.color = "花色";
function Animail(s) {
this.sex = s;
this.sleep = function () {
return "睡觉";
}
}
function Type(t) {
this.type = t;
}
//子类
function Cat(n, s,t) {
this.name = n;
this.eat = function () {
return "吃东西"
};
Animail.call(this, s);
Type.apply(this, [t]);
}
//实例化子类对象
var cat = new Cat("小猫", "公", "猫科"); //类对象在实例化的时候会直接执行自身的构造函数
console.log(cat);
三、实例继承
1. 继承方式:
在子类里面直接实例化父类得到对象,并在子类里面返回该对象。
2. 特点:
可以给父类传递参数,不限制调用方式3. 缺点:
- 不能多继承
- 不能继承子类的属性和方法,只能继承父类的属性和方法
- 子类的实例不是本身而是父类
//父类
function Person(n, s) {
this.name = n;
this.sex = s;
this.sleep = function () {
console.log(this.name + "睡觉");
}
}
//子类
function Child(n, s) {
var per = new Person(n, s);
return per;
}
//实例化子类对象
var child = new Child("张三", "女");
console.log(child);
四、组合继承
1. 继承方式:
构造继承+原型链继承
2. 特点:
- 构造继承和原型链继承的优缺点互补
- 实现多继承
- 调用了两次父类的构造函数
- 子类的实例即是本身也是父类
Person.prototype = {
job: function () {
return this.name + "job";
}
};
function Person(n) {
this.name = n;
this.sleep = function () {
return this.name + "睡觉";
}
}
function Child(n, a, s) {
this.age = a;
this.sex = s;
//构造继承
Person.call(this, n);
}
//原型链继承
Child.prototype = new Person();
var child = new Child("张三", 18, "男");
console.log(child);
五、寄生组合继承
1. 原理:
把父类的原型给予一个空对象的原型
2. 特点:
- 处理了组合继承的缺点,避免两次调用父类的构造函数
- 子类的实例即是本身也是父类
function Person(n) {
this.name = n;
this.sleep = function () {
return this.name + "睡觉";
}
}
function Child(n, a) {
this.age = a;
this.eat = function () {
return this.name + "吃饭"
};
Person.call(this, n);
}
//寄生
(function () {
var fn = function () {
};
//将父类的原型对象给予空对象
fn.prototype = Person.prototype;
Child.prototype = new fn();
})();
var child = new Child("李四", 20);
console.log(child);