javascript中的继承方式有哪些


本文摘自PHP中文网,作者V,侵删。

javascript中的继承方式有原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承和寄生组合式继承。其中组合继承是我们平时最常用的一种继承方式。

本文操作环境:windows10系统、javascript 1.8.5、thinkpad t480电脑。

在javascript中如果想要继承,那么我们就必须先提供一个父类,我们这里以Person来作为父类。

下文中所有构造函数名均无实际意义,如Coder、Rocker等,仅用于举例

1

2

3

4

5

6

7

8

function Person(name){//给构造函数添加了参数

            this.name=name;

            this.sex="male";

            this.say=function(){

                console.log(this.name);

            }

        }

Person.prototype.age=21;//给构造函数添加了原型属性

一、原型链继承

1

2

3

4

5

6

7

8

9

10

11

function Programmer(){

    this.name="Jayee";

}

 

Programmer.prototype=new Person();//子类构造函数.prototype=父类实例

 

var per1=new Programmer();

console.log(per1);//Programmer {name: "Jayee"}

console.log(per1.sex);//male

console.log(per1.age);//21

console.log(per1 instanceof Person);//true

重点:让新实例的原型等于父类的实例。Programmer.prototype=new Person();

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

缺点:1、新实例无法向父类构造函数传参。

   2、继承单一。

   3、所有新实例都会共享父类实例的属性。(原型上的属性是共享的,一个实例修

    改了原型的属性(per1.__proto__.sex=“female”,则per2.sex也会变成female),另

    一个实例的原型属性也会被修改!)

二、借用构造函数继承

1

2

3

4

5

6

7

8

9

10

11

//借用构造函数继承

function Coder(){

    Person.call(this,"Jayee");//重点:借用了Person

    this.age=18;

}

var cod1=new Coder();

console.log(cod1);

//Coder {name: "Jayee", sex: "male", hobby: "", age: 18, say: ?}

console.log(cod1.name);//Jayee

console.log(cod1.age);//18

console.log(cod1 instanceof Person);//false

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

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

    cod1.age是18而不是21可看出)

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

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

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

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

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

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

三、组合继承(组合原型链继承和借用构造函数继承)(常用)

1

2

3

4

5

6

7

8

9

10

//组合继承

function Typer(name){

    Person.call(this,name);

}

Typer.prototype=new Person();

var typ=new Typer("Jayee");

console.log(typ);

//Typer {name: "Jayee", sex: "male", hobby: "", say: ?}

console.log(typ.name);//Jayee,继承了构造函数

console.log(typ.age);//21,继承了父类的原型的属性

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

特点:1、可以继承父类原型上的属性,可以传参,可复用。
   2、每个新实例引入的构造函数属性是私有的。

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

四、原型式继承

1

2

3

4

5

6

7

8

9

10

11

//原型式继承

function Rocker(obj) {

//先封装一个函数容器,用来输出对象和承载继承的原型

    function F(){}

    F.prototype=obj;//继承了传入的函数

    return new F();//返回函数对象

}

var per=new Person();//拿到父类实例

var roc =Rocker(per);//F {}

console.log(per.__proto__);//{age: 21, constructor: ?}

console.log(roc.age);//21,继承了父类函数的属性

重点:用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了个可以随

意增添属性的实例或对象。object.create()就是这个原理。

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

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

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

五、寄生式继承

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

//寄生式继承

function Rocker(obj){

    function F(){}

    F.prototype=obj;//继承了传入的函数

    return new F();//返回函数对象

}

var per4=new Person();

//以上是原型式继承,给原型式继承再套个壳子传递参数

function Artist(obj){

    var roc=Rocker(obj);

    roc.name="Jayee";

    return roc;

}

var art = Artist(per4)

//这个函数经过声明之后就成了可增添属性的对象

console.log(typeof Artist);//function

console.log(typeof art);//object

console.log(art.name);//Jayee,返回了个roc对象,继承了roc的属性

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

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

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

六、寄生组合式继承(常用)

寄生:在函数内返回对象然后调用

组合:1、函数的原型等于另一个实例。2、在函数中用apply或者call引入另一个构造函数,可传参

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

//寄生式组合式继承

 

 //寄生

 function Rocker(obj){

    function F(){}

    F.prototype=obj;//继承了传入的函数

    return new F();//返回函数对象

}

//Rocker就是F实例的另一种表示法

var roc=new Rocker(Person.prototype);

//roc实例(F实例)的原型继承了父类函数的原型

//上述更像是原型链继承,只不过继承了原型属性

 

//组合

function Sub(){

    Person.call(this);

    //这个继承了父类构造函数的属性

    //解决了组合式两次调用构造函数属性的缺点

}

//重点

Sub.prototype=roc;//继承了roc实例

roc.constructor=Sub;//一定要修复实例

var sub1=new Sub();

//Sub的实例就继承了构造函数属性,父类实例,roc的函数属性

console.log(sub1.age);//21

重点:修复了组合继承的问题

七、ES6中的Class和extends

1

//todo

相关视频教程分享:javascript视频教程

以上就是javascript中的继承方式有哪些的详细内容,更多文章请关注木庄网络博客

相关阅读 >>

javascript怎么绑定事件

浏览器中5种常用的事件解析

javascript字符串转换函数是什么

javascript有哪些事件属性

如何理解javascript中的函数概念

javascript知识点总结之 jquery常用选择器和过滤选择器

javascript实现异步的方法有哪些

javascript怎么将数字转换成时间

五个超好用的array.from()用途(详解)

哪个不属于javascript的特征

更多相关阅读请进入《javascript》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...