大家好,我是蓝胖子的小叮当,今天分享的是JavaScript的第六章继承,大家在阅读期间有任何的意见或建议都可以留言给我哈!
继承简单来说,就是子类的实例可以访问父类上的属性和方法,以此实现减少重复代码、封装共有属性和方法、提高方法的多态性
下述讲解继承的七种方法
6.1 原型链继承
function Father(){
this.property = true;
}
Father.prototype.getFatherValue = function(){
return this.property;
}
function Son(){
this.sonProperty = false;
}
Son.prototype = new Father();
Son.prototype.getSonVaule = function(){
return this.sonProperty;
}
var instance = new Son();
alert(instance.getFatherValue());//true
缺点:
1.对象实例共享所有继承的属性和方法。
2.当原型链中包含引用类型值的原型时,该引用类型值会被所有实例共享
3.创建子类型实例的时候,不能传递参数,因为这个对象是一次性创建的
6.2 借用构造函数继承
function Father(){
this.colors = ["red","blue","green"];
}
function Son(){
Father.call(this);
}
var instance1 = new Son();
instance1.colors.push("black");
console.log(instance1.colors);//"red,blue,green,black"
var instance2 = new Son();
console.log(instance2.colors);//"red,blue,green"
缺点:
1.借用构造函数的缺点是方法都在构造函数中定义,因此无法实现函数复用。
2在父类型的原型中定义的方法,对子类型而言也是不可见的,结果所有类型都只能使用构造函数模式。
6.3 组合式继承
function Father(name){
this.name = name;
this.colors = ["red","blue","green"];
}
Father.prototype.sayName = function(){
alert(this.name);
};
function Son(name,age){
Father.call(this,name);
this.age = age;
}
Son.prototype = new Father();
Son.prototype.sayAge = function(){
alert(this.age);
}
var instance1 = new Son("louis",5);
instance1.colors.push("black");
console.log(instance1.colors);//"red,blue,green,black"
instance1.sayName();//louis
instance1.sayAge();//5
var instance1 = new Son("zhai",10);
console.log(instance1.colors);//"red,blue,green"
instance1.sayName();//zhai
instance1.sayAge();//10
缺点:会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次是在子类型构造函数内部
6.4 原型式继承
var person = {
friends : ["Van","Louis","Nick"]
};
var p1 = Object.create(person);
p1.friends.push("Rob");
var p2 = Object.create(person);
p2.friends.push("Style");
alert(person.friends);//"Van,Louis,Nick,Rob,Style"
缺点:属性中包含的引用值始终会在相关对象间共享,子类实例不能向父类传参
6.5 寄生式继承
function object(obj) {
function Fun() { };
Fun.prototype = obj;
return new Fun();
}
function createAnother(original){
var clone = object(original);
clone.sayHi = function(){
alert("hi");
};
return clone;
}
缺点:通过寄生式继承给对象添加函数会导致函数难以重用。使用寄生式继承来为对象添加函数, 会由于不能做到函数复用而降低效率;这一点与构造函数模式类似
6.6 组合寄生式继承
function objectCopy(obj) {
function Fun() { };
Fun.prototype = obj;
return new Fun();
}
function inheritPrototype(child, parent) {
let prototype = objectCopy(parent.prototype);
prototype.constructor = child;
Child.prototype = prototype;
}
function Parent(name) {
this.name = name;
this.hoby = ['唱', '跳']
}
Parent.prototype.showName = function () {
console.log('my name is:', this.name);
}
function Child(name, age) {
Parent.call(this, name);
this.age = age;
}
inheritPrototype(Child, Parent);
Child.prototype.showAge = function () {
console.log('my age is:', this.age);
}
let child1 = new Child("mjy", 18);
child1.showAge(); // 18
child1.showName(); // mjy
child1.hoby.push("rap");
console.log(child1.hoby); // ['唱', '跳', 'rap']
let child2 = new Child("yl", 18);
child2.showAge(); // 18
child2.showName(); // yl
console.log(child2.hoby); // ['唱', '跳']
6.7 class继承
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
sayName() {
console.log('Person')
}
}
class Animal extends Person {}
const a = new Animal()
a.sayName() // Person
6.8 总结
1.面向对象的类继承;2. 基于 JavaScript 原型链的原型继承;
前者的主要特点是:复制,通俗来说就是把变量、属性再复制一份,
后者的主要特点是:委托,通过属性的查找来实现的。
好啦,关于继承的知识点就总结到这里,如果有什么疑问、意见或建议,都可畅所欲言,谢谢大家,我也将持续更新。
预告:异步编程,解决回调地狱?欢迎收看JavaScript基础的下一章:Promise