js继承之原型链继承
面向对象编程都会涉及到继承这个概念,JS中实现继承的方式主要是通过原型链的方法。
一、构造函数、原型与实例之间的关系
每创建一个函数,该函数就会自动带有一个 prototype 属性。该属性是个指针,指向了一个对象,我们称之为 原型对象。什么是指针?指针就好比学生的学号,原型对象则是那个学生。我们通过学号找到唯一的那个学生。假设突然,指针设置 null, 学号重置空了,不要慌,对象还存在,学生也没消失。只是不好找了。
原型对象上默认有一个属性 constructor,该属性也是一个指针,指向其相关联的构造函数。
通过调用构造函数产生的实例,都有一个内部属性,指向了原型对象。所以实例能够访问原型对象上的所有属性和方法。
所以三者的关系是,每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。通俗点说就是,实例通过内部指针可以访问到原型对象,原型对象通过constructor指针,又可以找到构造函数。
下面看一个例子:
function Dog (name) {
this.name = name;
this.type = 'Dog';
}
Dog.prototype.speak = function () {
alert('wang');
}
var doggie = new Dog('jiwawa');
doggie.speak(); //wang
以上代码定义了一个构造函数 Dog(), Dog.prototype 指向的原型对象,其自带的属性construtor又指回了 Dog,即 Dog.prototype.constructor == Dog. 实例doggie由于其内部指针指向了该原型对象,所以可以访问到 speak方法。
Dog.prototype 只是一个指针,指向的是原型对象,但是这个原型对象并不特别,它也只是一个普通对象。假设说,这时候,我们让 Dog.protptype 不再指向最初的原型对象,而是另一个类 (Animal)的实例,情况会怎样呢?
二、原型链
前面我们说到,所有的实例有一个内部指针,指向它的原型对象,并且可以访问原型对象上的所有属性和方法。doggie实例指向了Dog的原型对象,可以访问Dog原型对象上的所有属性和方法;如果Dog原型对象变成了某一个类的实例 aaa,这个实例又会指向一个新的原型对象 AAA,那么 doggie 此时就能访问 aaa 的实例属性和 AA A原型对象上的所有属性和方法了。同理,新的原型对象AAA碰巧又是另外一个对象的实例bbb,这个实例bbb又会指向新的原型对象 BBB,那么doggie此时就能访问 bbb 的实例属性和 BBB 原型对象上的所有属性和方法了。
这就是JS通过原型链实现继承的方法了。看下面一个例子:
//定义一个 Animal 构造函数,作为 Dog 的父类
function Animal () {
this.superType = 'Animal';
} Animal.prototype.superSpeak = function () {
alert(this.superType);
} function Dog (name) {
this.name = name;
this.type = 'Dog';
}
//改变Dog的prototype指针,指向一个 Animal 实例
Dog.prototype = new Animal();
//上面那行就相当于这么写
//var animal = new Animal();
//Dog.prototype = animal; Dog.prototype.speak = function () {
alert(this.type);
}
var doggie = new Dog('jiwawa');
doggie.superSpeak(); //Animal
解释一下。以上代码,首先定义了一个 Animal 构造函数,通过new Animal()得到实例,会包含一个实例属性 superType 和一个原型属性 superSpeak。另外又定义了一个Dog构造函数。然后情况发生变化,代码中加粗那一行,将Dog的原型对象覆盖成了 animal 实例。当 doggie 去访问superSpeak属性时,js会先在doggie的实例属性中查找,发现找不到,然后,js就会去doggie 的原型对象上去找,doggie的原型对象已经被我们改成了一个animal实例,那就是去animal实例上去找。先找animal的实例属性,发现还是没有 superSpeack, 最后去 animal 的原型对象上去找,诶,这才找到。
(希望这张图对大家的理解有帮助吧。)
这就说明,我们可以通过原型链的方式,实现 Dog 继承 Animal 的所有属性和方法。
总结来说:就是当重写了Dog.prototype指向的原型对象后,实例的内部指针也发生了改变,指向了新的原型对象,然后就能实现类与类之间的继承了。(但是如果在重写原型对象之前,产生的实例,其内部指针指向的还是最初的原型对象。这个我下次再发篇文章讲。js 继承之借用构造函数继承)
如果你觉得文章解决了你的疑惑的话,还请赏我一个推荐哦~ :)
作者不才,文中若有错误,望请指正,避免误人子弟。
文章内容全都参考于《JAVASCRIPT 高级程序设计》
js继承之原型链继承的更多相关文章
- javascript中继承(一)-----原型链继承的个人理解
[寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...
- 一步步学习javascript基础篇(5):面向对象设计之对象继承(原型链继承)
上一篇介绍了对象创建的几种基本方式,今天我们看分析下对象的继承. 一.原型链继承 1.通过设置prototype指向“父类”的实例来实现继承. function Obj1() { this.name1 ...
- Typescript中的类 Es5中的类和静态方法和继承(原型链继承、对象冒充继承、原型链+对象冒充组合继承)
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...
- 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)
摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...
- js原型链理解(2)--原型链继承
1.原型链继承 2.constructor stealing(构造借用) 3.组合继承 js中的原型链继承,运用的js原型链中的__proto__. function Super(){ this.se ...
- 一篇JavaScript技术栈带你了解继承和原型链
作者 | Jeskson 来源 | 达达前端小酒馆 1 在学习JavaScript中,我们知道它是一种灵活的语言,具有面向对象,函数式风格的编程模式,面向对象具有两点要记住,三大特性,六大原则. 那么 ...
- JS中原型链继承
当我们通过构造函数A来实现一项功能的时候,而构造函数B中需要用到构造函数A中的属性或者方法,如果我们对B中的属性或者方法进行重写就会出现冗杂的代码,同时写出来也很是麻烦.而在js中每个函数都有个原型, ...
- JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链
相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...
- js继承之组合继承(结合原型链继承 和 借用构造函数继承)
在我的前两篇文章中,我们已经介绍了 js 中实现继承的两种模式:原型链继承和借用构造函数继承.这两种模式都存在各自的缺点,所以,我们考虑是否能将这二者结合到一起,从而发挥二者之长.即在继承过程中,既可 ...
随机推荐
- python 面向对象编程(一)
一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法. 类是对现实世界中一些事物的封装,定义一个类可以采用下面的方式来定义: class c ...
- NuGet(Nuget Packages)
Nuget是一个.NET平台下的开源的项目,它是Visual Studio的扩展.在使用Visual Studio开发基于.NET Framework的应用时,Nuget能把在项目中添加.移除和更新引 ...
- 除去ubuntu的grub引导
除去ubuntu的grub引导 step如下>> 进入ubuntu终端 sudo gedit /etc/defauli/grub 将 #GRUB_HIDDEN_TIMEOUT=0 最前面的 ...
- 实现TOLock过程中的一处多线程bug
背景 最近在啃<多处理器编程的艺术>,书中的7.6节介绍了时限锁--实现了tryLock方法的队列锁. 书中重点讲解了tryLock的实现,也就是如何实现在等待超时后退出队列,放弃锁请求, ...
- springmvc学习笔记(简介及使用)
springmvc学习笔记(简介及使用) 工作之余, 回顾了一下springmvc的相关内容, 这次也为后面复习什么的做个标记, 也希望能与大家交流学习, 通过回帖留言等方式表达自己的观点或学习心得. ...
- 少年,是时候换种更优雅的方式部署你的php代码了
让我们来回忆下上次你是怎么发布你的代码的: 1. 先把线上的代码用ftp备份下来 2. 上传修改了的文件 3. 测试一下功能是否正常 4. 网站500了,赶紧用备份替换回去 5. 替换错了/替换漏了 ...
- java设计模式--基础思想总结--父类引用操作对象
看设计模式的相关书籍也有一段时间了,一开始其实是抱着作为java三大框架的基础知识储备来学习的,不过到后来,才发现,在设计模式的一些准则装饰下,java的面向对象威力才真正地体现出来,后面的将会陆续地 ...
- bootstrap快速入门笔记(七)-表格,表单
一,表格 1,<table>中加.table类 2,条纹表格:通过 .table-striped 类可以给 <tbody> 之内的每一行增加斑马条纹样式. **跨浏览器兼容性: ...
- (原创)看我用各种姿势在手机和PC查看到连接到的wifi密码
今天一个女神来我家做客,她问我WiFi密码,然而我却奇迹般的忘记了(特么的当时心里一万个草泥马踏过去),让我在她面前尴尬求子的,所以为了防止你们也出现这种情况,我特地把各种方法整理了一下,那么感兴趣的 ...
- 系统启动 之 Linux系统启动概述(1)
随着智能终端功能的越来越庞大,与之,硬件配置越来越高,开机时间却越来越长.人们在享受强大功能的同时,对冗长的智能终端的开机时间却越来越缺乏耐心. 为了"取悦"用户,需要提供较好的用 ...