继承有几种方式,分别是什么,想要实现继承可以使用哪些方法

1.背景介绍

简介

在JS中继承是一个非常复杂的话题,比其他任何面向对象语言中的继承都复杂得多。在大多数其他面向对象语言中,继承一个类只需使用一个关键字即可。在JS中想要达到继承公用成员的目的,需要采取一系列措施。

2.知识剖析

继承有哪些方法可以实现?

2.1.原型链

原型链的基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。

实现原型链有一种基本模式,其代码大致如下:

function Fn1() {

this.property = true;//this绑定Fn1新对象

}//构造函数模式,函数名需大写

Fn1.prototype.getSuperValue = function () {

return this.property;

};

function Fn2() {

this.subproperty = false;

}//继承了fn1

Fn2.prototype = new Fn1();

console.log(Fn2.prototype.property);//true

Fn2.prototype.getSubValue = function () {

return this.subproperty;

};

var instance = new Fn2();

console.log(instance.getSuperValue());//true

2.2.借用构造函数

在解决原型中包含引用类型值所带来问题的过程中,开发人员开始使用一种叫做借用构造函数的技术。这种技术的基本思想非常简单,即在子类型构造函数的内部调用超类型构造函数。一般都是通过apply()和call()方法也可以在新创建的对象上执行构造函数。

function Fn1() {

this.colors = ['red', 'blue', 'green'];

}

function  Fn2() {

Fn1.call(this);//继承了Fn1对象

}

var instance1 = new Fn2();

instance1.colors.push('black');

console.log(instance1.colors);//'red','blue','green','black'

var instance2 = new Fn2();

console.log(instance2.colors);//'red','blue','green'*/

2.3.组合继承

组合继承,有时候也叫做伪经典继承,指的是将原型链和借用构造函数的技术组合在一块,从而发挥二者之长的一种继承模式。其背后的思路是使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。。这样,既通过在原型上定义方法实现了函数复用,又能够保证每个实例都有它自己的属性。

function Fn1(name) {

this.name = name;

this.colors = ['red','blue','green'];

}

Fn1.prototype.sayName = function () {

console.log(this.name);

};

function  Fn2(name,age) {

Fn1.call(this, name);//继承Fn1属性

this.age = age;

}

//方法(函数)继承

Fn2.prototype = new Fn1();//继承Fn1的原型prototype

Fn2.prototype.constructor = Fn2;//构造函数指向F2对象

Fn2.prototype.sayAge=function () {

console.log(this.age);

};

var instance1 = new Fn2('Nicholas',29);

instance1.colors.push('black');

console.log(instance1.colors);//'red','blue','green','black'

instance1.sayName();//'Nicholas'

instance1.sayAge();//29

var instance2 = new Fn2('Freg',27);

console.log(instance2.colors);//'red','blue','green'

instance2.sayName();//'Greg'

instance2.sayAge();//27

2.4.原型式继承

道格拉斯·克罗克福德在一篇文章中介绍一种实现继承的方法,这种方法并没有实现严格意义上的构造函数。通过借助原型可以给予已有的对象创建新对象,同时还不必因此创建自定义类型。

function object(o) {

function F() {}

F.prototype = o;

return new F();

}//借助原型可以基于已有的对象创建新对象

var person = {

name:"Nicholas",

friends:["Shelby","Court","Van"]

};

var anotherPerson = object(person);//相当于var anotherPerson = Object.create(person);

anotherPerson.name = "Greg";

anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);//相当于var yetAnotherPerson = Object.create(person);

yetAnotherPerson.name = "Linda";

yetAnotherPerson.friends.push("Barbie");

console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"*/

2.5.寄生式继承

寄生式继承是与原型式继承紧密关联的一种思路,即创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再想真地是它做了所有工作一样返回对象

function object(o) {

function F() {}

F.prototype = o;

return new F();

}//借助原型可以基于已有的对象创建新对象

function createAnother(original) {

var clone = object(original);//通过调用函数创建一个新对象

clone.sayHi = function () { //以某种方式来增强这个对象

console.log("hi");

};

return clone;//返回这个对象

}

var person = {

name:"Nicholas",

friends:["Shelby","Court","Van"]

};

var anotherPerson = createAnother(person);

anotherPerson.sayHi();

2.6.寄生组合式继承

所谓寄生性继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。

function object(o) {

function F() {}

F.prototype = o;

return new F();

}

function  inheritPrototype(subType,superType) {

var prototype = object(superType.prototype);//创建对象

prototype.constructor=subType;//增强对象

subType.prototype=prototype;//指定对象

}

function Fn1(name) {

this.name = name;

this.colors=["red","blue","green"];

}

Fn1.prototype.sayName=function () {

console.log(this.name);

};

function Fn2(name,age) {

Fn1.call(this,name);//继承Fn1的对象属性

this.age=age;

}

inheritPrototype(Fn1,Fn2);

Fn2.prototype.sayAge = function () {

console.log(this.age);

};

var instance=new Fn2("Nicholas",29);

instance.sayAge();//29

console.log(instance.colors);//["red","blue",""green]

console.log(instance.name);//Nicholas

3.常见问题

在以上的继承方式中,哪些继承方式比较好?

4.解决方案

现阶段中运用比较广泛的是组合式继承,因为原型链和构造函数继承方式都有相对应的缺点,比如说原型链最主要的问题来自包含引用类型值的原型。而构造函数的缺点是不能很好地封装对象方法。一般情况下只有对象没有方法的情况下才会使用构造函数。而组合式继承继承了原型链和构造函数的优点,并完善了二者的不足。function Fn1(){

this.colors=["red","blue","green"];

}

function Fn2(){

}

Fn2.prototype=new Fn1();//继承了Fn1()对象

var instance1 = new Fn2();

instance1.colors.push("black");

console.log(instance1.colors);//"red","blue","green","black"

var instance2 = new Fn2();

console.log(instance2.colors);//"red","blue","green","black"

5.编码实战

6.扩展思考

前面讲过寄生组合式继承和组合式继承,这两者有什么区别?

前面说过,组合式继承是javascript最常用的继承模式;表格,它也有自己的不足。组合继承最大的问题就是无论在什么情况下,都会调用2次超类型构造函数。而寄生组合式继承可以很好的解决这个问题。

7.参考文献

javascript高级程序设计



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,717评论 2 17
  • 单例模式 适用场景:可能会在场景中使用到对象,但只有一个实例,加载时并不主动创建,需要时才创建 最常见的单例模式,...
    Obeing阅读 2,054评论 1 10
  • 1、构造函数模式 [url=]file:///C:/Users/i037145/AppData/Local/Tem...
    横冲直撞666阅读 842评论 0 0
  • 关键词:好人和好的团队 人之初善恶 集体和个体意识 原始规则 道德和制度 系统性和局部...
    几0一阅读 699评论 0 1
  • 姓名:赵磊 公司:宁波长晟电子科技有限公司 宁波盛和塾《六项精进》235期学员。 【日精进打卡第12天】 【知~学...
    白鹤亮翅_ab4a阅读 236评论 0 0