JS 的继承

JS的继承一共有6种方式
首先我们需要提供一个父类来给新的实例继承

function Person(name){
this.name = name;
this.sun = function(){
  alert(this.name);
  }
}
Person.prototype.age = 18;

原型链继承

让新的实例的原型等于其父类的原型
实例可继承的属性有: 实例的构造函数的属性、父类构造函数的属性、父类原型的属性。
但是原型链继承的新实例无法向父类构造函数传参,并且继承单一,所有新的实例都会共享父类实例的属性,其中一个实例的原型属性被修改了,另一个属性的实例原型也会被修改。

function people(){
this.name = "Thomas" ;
}
people.prototype = new Person();//原型链开始继承
var people1 = new people();
console.log (people1.age);
console.log(people1 instanceof Person);//instanceof 判断元素是否在另一个元素的原型链上,如果是则返回true

借用构造函数继承

用 .call() 和 .apply()方法将父类构造函数引入子类函数
使用该方式继承,新的实例只继承父类构造函数的属性,不继承父类原型的属性。能解决以下问题:原型链继承的新实例无法向父类构造函数传参,并且继承单一,所有新的实例都会共享父类实例的属性,其中一个实例的原型属性被修改了,另一个属性的实例原型也会被修改。
并且通过这种方式可以继承多个构造函数的属性(call多个),子实例可以向父实例传参。
但是这种方式只能继承父类构造函数的属性,并且无法实现构造函数的重复使用,每次使用时都要重新调用。由于每个新的实例都有父类构造函数的副本,所以结构显得臃肿。

function Con(){
  Person.call(this,"construct");
  this.age = 12;
}
var con1 = new Con();
console.log(con.name);//construct
console.log(con.age);//12
console.log(con1 instanceof Person);//false

组合继承

这是比较常用的继承方式,它可以向夫类构造函数传参数,并且可以复用。
但是这种方法会调用两次父类构造函数,比较消耗内存,同时子类的构造函数会代替原型上的父类构造函数。

function SubType(name){
Person.call(this,name);//借用构造函数继承的方式
}
SubType.prototype = new Person();//原型链继承
var sub = new SubType("combine");//
console.log(sub.name);//"combine"继承了构造函数属性
console.log(sub.age);//18继承了父类原型的属性

原型式继承

用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了可以随意增添属性的实例或对象。object.create() 就是这个原理。它类似于复制一个对象,用函数来包装。
但是使用这种方式创建的实例都会继承原型上的属性,并且无法实现复用。

function content(obj){
  function F(){} //函数容器
  F.prototype = obj;//继承了传入的参数
  return new F();//返回函数对象
}
var sup = new Person();//得到父类的实例
var sup1 = content(sup);//返回的F()中有了父类函数的属性
console.log(sup1.age);//18 继承了父类函数的属性

寄生式继承

在原型式继承外面套了个壳,没有创建自定类型,因为只是套了个壳子返回对象,这个函数顺理成章成了创建的新对象。但是没用到原型无法复用

function content(obj){
function F(){};
F.prototype = obj;
return new F();
}
var sup = new Person();//到这里为止都是原型式继承,给原型式集成在套个壳子用来传递参数
function subObject(obj){
  var sub = content(obj);
  sub.name = "subName";
return sub;
}
var sub2 = subObject(sup);//得到了返回的sup对象,该对象可以添加属性
console.log(typeof subObject);//subObject 是function
console.log(typeof sub2);//sub2是object
console.log(sub2.name);//"subName"继承了sub的属性

寄生组合式继承

这个比较常用。
寄生式继承是在函数内返回对象然后调用
寄生组合式继承方式的特点是:
函数的原型等于另一个实例,在函数中用apply或者call引入另一个构造函数,可传参。

function content(obj){
  function F(){};
  F.prototype = obj;
  return new F();
}//返回包裹了 obj 的F()
var con = content (Person.prototype);
//创建con实例 其中 con.__proto__ === Person.prototype,它继承了原型属性
function Sub(){
  Person.call(this);//这个继承了父类构造函数的属性
}//解决了组合式两次调用构造函数属性的缺点
Sub.prototype = con;//继承con实例
con.constructor = Sub;//修复实例
var sub1 = new Sub();//Sub的实例继承了构造函数属性、父类实例、con的函数属性
console.log(sub1.age);//18
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 作者:撒网要见鱼http://www.dailichun.com/2018/01/15/howtoextendda...
    grain先森阅读 3,926评论 0 3
  • 想要继承就必须提供一个父类 1.原型链继承 重点:让新实例的原型等于父类的实例。 特点:1、实例可继承的属性有:实...
    木子川页心阅读 3,613评论 0 0
  • 继承的概念:子类可以使用父类共享的属性和方法,避免重复代码提高代码复用性。 原型链:子类可以共享父类的实例对象和实...
    浅秋_6672阅读 3,034评论 0 0
  • 原文链接 js的继承有6种方式,大致总结一下它们各自的优缺点,以及它们之间的关系。 1.原型链 js的继承机制不同...
    空_城__阅读 4,123评论 0 11
  • 提到JS继承,你首先想到的什么? 面试 继承方式 优缺点...,js继承作为曾经的苦主,我看了忘,忘了看,看了又忘...
    唐_银阅读 3,382评论 0 6