JavaScript基础(六)继承

28 阅读3分钟

大家好,我是蓝胖子的小叮当,今天分享的是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