文档章节

JavaScript继承(一)——原型链

Bob2100
 Bob2100
发布于 01/06 12:40
字数 1047
阅读 17
收藏 2

继承是面向对象语言中一个最为人津津乐道的概念。许多面向对象语言都支持两种继承方式:接口继承和实现继承。接口继承只继承方法签名,而实现继承则继承实际的方法。在ECMAScript中,函数没有签名,无法实现接口继承,只支持实现继承,继承主要依靠的是原型链。

先来看一个简单的原型链继承示例,如下图:

首先声明一个Human函数,给它的原型添加一个getHumanSex方法。然后声明一个Person函数,要让Person继承Human,能使用Human的属性和方法,只要把Person的原型重新赋值为Human的一个实例就好了。最后给Person的原型(也就是Human的这个实例)添加一个getPersonSex方法。现在创建Person的一个实例personObjname = '张三',age = 12。如果访问personObj.name,那么就可以直接访问到是张三了。假如现在要访问humanSex,因为personObj中没有,所以会顺着__proto__属性到Person的原型中去找,而Person的原型就是Human的一个实例,它的humanSex属性就是'男/女',所以personObj.humanSex的值就是'男/女',这就达到了继承的效果。假如要访问getPersonSexpersonObj中没有,也是到原型中去找,找到了就调用,因为是使用personObj.getPersonSex,所以在方法getPersonSex中,this指的就是personObjreturn this.personSex就是返回personObj.personSex,即为'男'。 如果是调用personObj.getHumanSex,还是先顺着__proto__Person的原型中去找,Person的原型是Human的一个实例,里面没有,那怎么办呢,因为该原型是Human的一个实例,所以它自然也会有个__proto__指向Human的原型,于是就继续顺着这个__proto__Human的原型中去找,这就是所谓的原型链,找到了就开始调用,自然getHumanSex中的this指的也就是personObjreturn this.humanSex就是return personObj.humanSex,即'男/女'。这就是原型链继承。

细心的读者也许会发现,在Human的原型中也有个__proto__,那么Human的原型会不会也是某个函数的一个实例呢?如果我们调用personObj.toString(),那么我们调用的究竟是谁的toString()呢?要回答这个问题,我们来看下面这幅示意图:

Human的原型其实是Object的一个实例,自然__proto__指向的就是Object的原型,而toString就是Object原型上的方法。

其实ECMAScript中所有引用类型的默认原型都是Object的实例,也就是说所有引用类型默认都继承了Object,而这个继承正是通过原型链实现的。

原型的好处是所有的实例能共享它所包含的属性和方法,也就是说不必在构造函数中定义对象实例的信息,但正如JavaScript创建对象(三)——原型模式中所说,这也带来了一个问题。原型属性会被所有实例共享,对于引用类型会出现一些应用时的共享问题,所以需要在构造函中,而不是在原型对象中定义属性。但是在通过原型来实现继承时,原型实际上就是另一个函数的实例。于是,原来的实例属性也就顺理成章地变成了现在的原型属性了,那么原型共享数据的问题又出现了。

另外一个问题是,创建子类型的实例时,没法向超类型的构造函数中传递参数。实际上,应该说是没办法在不影响所有对象的实例下,给超类型的构造函数传递参数。有鉴于此,实践中很少会单独使用原型链。

© 著作权归作者所有

共有 人打赏支持
Bob2100
粉丝 23
博文 85
码字总数 46053
作品 0
浦东
高级程序员
私信 提问
JavaScript继承(六)——寄生组合式继承

JavaScript继承(三)——组合继承中讲到,组合继承是JavaScript中最常用的继承模式,但是它也有自己的不足之处,现在我们就来剖析它的不足,如下示例: 使用组合继承让继承实际上分为两步:...

Bob2100
02/16
0
0
每个JavaScript工程师都应懂的33个概念

摘要: 基础很重要啊! 原文:33 concepts every JavaScript developer should know 译文:每个 JavaScript 工程师都应懂的33个概念 作者:stephentian Fundebug经授权转载,版权归原作者所有...

Fundebug
2018/10/30
0
0
JavaScript继承(二)——借用构造函数

JavaScript继承(一)——原型链中提出原型链继承的两个问题:一是原型的数据共享问题,二是创建子类型的实例时,不能向父类型的构造函数中传递参数。这两个问题的根源还是在于使用原型模式创...

Bob2100
01/20
0
0
JavaScript开发者应懂的33个概念

简介 这个项目是为了帮助开发者掌握 JavaScript 概念而创立的。它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南。 本篇文章是参照 @leonardomso 创立,英文版项目地址在这里。 ...

大灰狼的小绵羊哥哥
2018/10/22
0
0
JavaScript继承(四)——原型式继承

道格拉斯·克罗克福特在2006年提出了原型式继承,他的想法是基于已有的对象借助原型创建新对象,同时还不必因此创建一个自定义类型。为此,他给出了下面的函数: 在函数内部,先创建了一个临...

Bob2100
02/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

StringRedisTemplate的使用

《如何使用RedisTemplate访问Redis数据结构》

yan_liu
3分钟前
0
0
好程序员大数据教程Hadoop全分布安装(非HA)

  机器名称 启动服务   linux11 namenode secondrynamenode datanode   linux12 datanode   linux13 datanode   第一步:更改主机名,临时修改+永久修改   临时修改:hostname ...

好程序员IT
7分钟前
0
0
案例:通过shell脚本实现mysql数据备份与清理

Shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命令并把它送入内核去执行,实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核,不仅...

Linux就该这么学
12分钟前
0
0
springmvc源码解析之@EnableWebMvc五

说在前面 本次主要介绍springmvc配置解析。关注“天河聊架构”微信公众号有更多精彩。 springmvc配置解析 @EnableWebMvc这个注解干了什么,初始化HandlerExceptionResolver 进入到这个方法o...

天河2018
13分钟前
0
0
开源 java CMS - FreeCMS2.8 数据对象 user

项目地址:http://www.freeteam.cn/ user 在使用用户相关标签时,标签会封装user供页面调用。 属性 说明 id id ismail 是否接收互动信件 name 名称 unitNames 所属单位名称,多个之间用;号分...

freeteam
21分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部