您现在的位置是:首页 > 文章详情

javascript 几种常用继承方法和优缺点分析

日期:2019-01-25点击:436

1.原型链继承(最简单)

核心 (实现思路):用父类的实例充当子类原型对象

function Person(name) { this.name = name; this.fav = ['basketball', 'football']; this.detail = {country : '中国', city : '江苏'} } function Man(name) { this.say = function(){console.log('I am man')}; } Man.prototype = new Person(); //核心 var sam = new Man('sam'); console.log(sam.fav); //'basketball', 'football'

优点

1.简单,容易理解,容易实现

缺点:

1.创建子类实例时无法向父类传参(创建Man时无法传递name信息)

2.引用类型的属性(数组和对象),被所有实例共享,接着上面的代码举个例子

var tyler = new Man('tyler'); tyler.fav.push('badminton'); tyler.rela.area = '建业区' //修改tyler实例的信息,间接地修改了sam实例的属性 console.log(sam.fav) // "basketball", "football", "badminton" console.log(sam.rela) // {country:'中国',city:'江苏',area:'建邺区'}

2.借用构造函数(经典继承)

为了解决原型链继承的两个问题,所以就有了借用构造函数的继承方法。

核心 (实现思路):借父类的构造函数,补充子类的构造函数,相当于把父类的实例属性拷贝一份给子类的实例

function Person(name) { this.name = name; this.fav = ['basketball', 'football']; this.say = function(){console.log('I love china')} } function Man(name) { Person.call(this, name); //核心 } var sam = new Man('sam'); var tyler = new Man('tyler'); tyler.fav.push('badminton'); console.log(sam.name); //sam console.log(tyler.name); //tyler console.log(sam.fav); //'basketball', 'football' console.log(tyler.fav); //'basketball', 'football', 'badminton' console.log(sam.say == tyler.say) //false

优点:

1.解决了原型链继承中 实例共享引用类型属性的问题

2.修改了原型链继承中 子类构建无法向父类传递参数的问题

缺点:

1.代码的最后一行显示两个子类实例中的方法并非同一个,即无法实现函数复用,如果实例多的情况下影响性能

3.组合继承(常用)

原型链继承和借用构造函数继承的组合

核心 (实现思路):把实例函数都放在父类的原型对象上面,实现函数复用,同时保留借用构造函数的实现思路。

function Person(name) { this.name = name; this.fav = ['basketball', 'football']; } Person.prototype.say = function(){console.log('I love china')} function Man(name) { Person.call(this, name); //核心 } Man.prototype = new Person(); var sam = new Man('sam'); var tyler = new Man('tyler'); tyler.fav.push('badminton'); console.log(sam.name); //sam console.log(sam.fav); //'basketball', 'football' console.log(sam.say == tyler.say) //true

优点:

1.没有实例共享引用类型的属性的问题

2.子类构造实例时可以通过父类传递参数

3.实现了函数复用

缺点:

1.唯一缺点就是创建一个子类实例时,会调用两次父构造函数,从上面的代码中sam 和Man.prototype 中都包含 fav属性

4.寄生组合式继承(最佳)

为了解决组合继承中的不足,计生组合式继承应运而出了

核心 (实现思路):使用壳函数切掉了原型对象上多余的父类属性

//代码1 function Person(name) { this.name = name; this.fav = ['basketball', 'football']; } Person.prototype.say = function(){console.log('I love china')} function Man(name) { Person.call(this, name); } //关键三步代码 var F = function () {}; F.prototype = Person.prototype; Man.prototype = new F(); var sam = new Man('sam'); console.log(sam.name); //代码2 :对继承的关键三部进行封装 function Person(name) { this.name = name; this.fav = ['basketball', 'football']; } Person.prototype.say = function(){console.log('I love china')} function Man(name) { Person.call(this, name); } function create(o) { function F(){}; F.prototype = o; return new F(); } function inheritFunc(child, parent) { var newPrototype = create(parent.prototype); //如果没有下面一行代码,sam.constructor会变称Person 而不是Man newPrototype.constructor = child; child.prototype = newPrototype; } var sam = new Man('sam'); console.log(sam.name); 

优点:

没有任何缺点就是优点(如果使用麻烦不算缺点的话)

缺点:

理解起来比较绕,使用比较麻烦

 

原文链接:https://my.oschina.net/kimyeongnam/blog/3006004
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章