龙空技术网

JavaScript继承的几种方式

simon锋 203

前言:

而今兄弟们对“js的继承方式有哪些”大约比较讲究,看官们都需要知道一些“js的继承方式有哪些”的相关文章。那么小编也在网络上搜集了一些有关“js的继承方式有哪些””的相关知识,希望大家能喜欢,各位老铁们一起来了解一下吧!

1. 原型链继承

原型链继承:想要继承,就必须要提供父类(继承谁,提供继承的属性)

//父级function Person(name) {   //给构造函数添加参数    this.name = name;    this.age = 10;    this.sum = function (){        console.log(this.name)    }}//原型链继承function Per() {    }Per.prototype = new Person(); //主要 实现继承var per1 = new Per();console.log(per1.age);  //10

重点:让新实例的原型等于父类的实例

特点:1.实例可继承的属性有:实例的构造函数的属性,父类构造函数属性,父类原型的属性。(新实例不会继承父类实例的属性!)

缺点:

1>新实例无法向父类构造函数参数。

2>父子构造函数的原型对象之间有共享问题

2. 借用构造函数继承

使用call和apply借用其他构造函数的成员, 可以解决给父构造函数传递参数的问题, 但是获取不到父构造函数原型上的成员.也不存在共享问题

//父级function Person(name) {   //给构造函数添加参数    this.name = name;    this.age = 10;    this.sum = function (){        console.log(this.name)    }}//子构造函数function Per(name) {    //使用call借用Person的构造函数    Person.call(this,name)}//测试是否有了Person的成员var stn = new Per('我是');stn.sum();   //   我是console.log(stn.age)

重点:用.call()和.apply()将父类构造函数引入子类函数(在子类函数中做了父类函数的自执行(复制))

缺点:1、只能继承父类构造函数的属性。

   2、无法实现构造函数的复用。(每次用每次都要重新调用)

   3、每个新实例都有父类构造函数的副本,臃肿。

特点:1、只继承了父类构造函数的属性,没有继承父类原型的属性。

   2、解决了原型链继承缺点1、2、3。

   3、可以继承多个构造函数属性(call多个)。

   4、在子实例中可向父实例传参。

3. 组合继承

借用构造函数 + 原型式继承

//父级function Person(name) {   //给构造函数添加参数    this.name = name;    this.age = 10;    this.sum = function (){        console.log(this.name)    }}//创建子构造函数function Per(name) {    Person.call(this,name); //借用构造函数}Per.prototype = new Person() //继承原型链继承var str = new Per('zhao');console.log(str.name); //'zhao'  是继承了Per子构造函数的属性console.log(str.age);  // 10   是继承了Person父类原型的属性

重点:结合了两种模式的优点,传参和复用

特点:1、可以继承父类原型上的属性,可以传参,可复用。

   2、每个新实例引入的构造函数属性是私有的。

缺点:调用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数

4. 原型链继承

//父级function Person(name) {   //给构造函数添加参数    this.name = name;    this.age = 10;    this.sum = function (){        console.log(this.name)    }}//设置父构建函数的原型Person.prototype.fn = function (){    console.log(this.age)}//构建子构造函数function Per() {}//实现继承var str = new Person(); //拿到父类的实例console.log(str.age);  // 10str.fn();    10

重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随意增添属性的实例或对象。object.create()就是这个原理。

特点:类似于复制一个对象,用函数来包装。

缺点:1、所有实例都会继承原型上的属性。

   2、无法实现复用。(新实例属性都是后面添加的)

5. 寄生式继承

//父级function Person(name) {   //给构造函数添加参数   function fn(){}   fn.prototype = name; //继承传入的参数   return new fn();  //返回函数对象}var str = new Person();//以上是原型式继承,给原型式继承在套一个壳子传递参数 function Per(name) {    var fn1 = Person(name);    fn1.name = "zhao";    return fn1}var fn3 = Per(str);console.log(fn3.name); //返回str对象,继承了str的属性

重点:就是给原型式继承外面套了个壳子。

优点:没有创建自定义类型,因为只是套了个壳子返回对象(这个),这个函数顺理成章就成了创建的新对象。

缺点:没用到原型,无法复用

6. 寄生组合式继承

function Person(name){    this.name = name;    this.hobbies = ['a','b','v']};function student(name,age){    Person.call(this,name);    this.age = age;}//关键的三步 实现继承// 使用F空函数当子类和父类的媒介 是为了防止修改子类的原型对象影响到父类的原型对象let fn = function (){};fn.prototype = Person.prototype;student.prototype = new fn();var fn1 = new student('zhao','24')console.log(fn1)

组合继承最大的缺点是最调用两次父构造函数

一次是设置子类实例的原型的时候:

 student.prototype = new Person();

一次是在创建子类型实例的时候:

var fn = new student('zhao','24')
7. es6实现继承
class parents {    constructor(){        this.grandmather = 'rose';        this.grandfather = 'jack';    }}class children extends parents{    constructor(mather,father){    //super 关键字,它在这里表示父类的构造函数,用来新建父类的 this 对象。        super();        this.mather = mather;        this.father = father;    }}let child = new children('mama','baba');console.log(child)

标签: #js的继承方式有哪些