js 原型链、构造函数、原型与实例之间的关系
面向对象编程都会涉及到继承这个概念,JS中实现继承的方式主要是通过原型链的方法。
一、构造函数、原型与实例之间的关系
每创建一个函数,该函数就会自动带有一个 prototype 属性。该属性是个指针,指向了一个对象,我们称之为 原型对象。什么是指针?指针就好比学生的学号,原型对象则是那个学生。我们通过学号找到唯一的那个学生。假设突然,指针设置 null, 学号重置空了,不要慌,对象还存在,学生也没消失。只是不好找了。
原型对象上默认有一个属性 constructor,该属性也是一个指针,指向其相关联的构造函数。
通过调用构造函数产生的实例,都有一个内部属性,指向了原型对象。所以实例能够访问原型对象上的所有属性和方法。
所以三者的关系是,每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。通俗点说就是,实例通过内部指针可以访问到原型对象,原型对象通过constructor指针,又可以找到构造函数。
下面看一个例子:
|
1
2
3
4
5
6
7
8
9
|
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 继承之借用构造函数继承)
js 原型链、构造函数、原型与实例之间的关系的更多相关文章
- Jascript原型链以及Object和Function之间的关系
先看一个简单的function变量 function fun1(name) { this.name = name; } console.log("fun1", fun1) 从结果可 ...
- JavaScript原型链以及Object,Function之间的关系
JavaScript里任何东西都是对象,任何一个对象内部都有另一个对象叫__proto__,即原型,它可以包含任何东西让对象继承.当然__proto__本身也是一个对象,它自己也有自己的__proto ...
- Javascript 构造函数、原型对象、实例之间的关系
# Javascript 构造函数.原型对象.实例之间的关系 # 创建对象的方式 # 1.new object() 缺点:创建多个对象困难 var hero = new Object(); // 空对 ...
- 从零开始学 Web 之 JS 高级(二)原型链,原型的继承
大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...
- js 原型,原型链,原型链继承浅析
对于网上的关于原型,原型链和原型链继承的晦涩语言说明就不累赘了,复制粘贴过来再解释一遍怕自己也整蒙了,本人最怕空气突然安静,四目对视,大眼对小眼,一脸懵逼. 我们先看下面
- jacascript中的原型链以原型
今地铁上看慕课网js课程,又学习到关于原型的一些知识,记录如下.如有偏差欢迎指正: 三张图要连起来看哦~ 图解: 1.创建一个函数foo. 2.运用函数的prototype属性(这个属性就是实例对象的 ...
- 275 原型与原型链:显式原型prototype ,隐式原型__proto__,隐式原型链,原型链_属性问题,给原型对象添加属性/方法
1.所有函数都有一个特别的属性 prototype : 显式原型属性 [普通构造函数的实例对象没有prototype 属性,构造函数有__proto__属性,原型对象有__proto__属性 ] 2. ...
- Javascript原型链和原型继承
哇好久都没有写随笔啦,整个人都慵懒啦. 为了不让大家忘记我,把以前写过的一些慢慢发出来. 在JS 中, 有两条链子,作用域链 和 原型链. 作用域链相对容易理解,两点 - 函数限定变量作用域,就是说, ...
- 前端知识体系:JavaScript基础-原型和原型链-理解原型设计模式以及 JavaScript中的原型规则
理解原型设计模式以及 JavaScript中的原型规则(原文地址) 1.原型对象:我们创建的每一个函数(JavaScript中函数也是一个对象)都有一个原型属性 prototype,原型属性实质上是一 ...
随机推荐
- centos 配置rsync+inotify数据实时同步2
一.Rsync服务简介 1. 什么是Rsync 它是一个远程数据同步工具,它在同步文件的同时,可通过LAN/WAN快速同步多台主机间的文件.Rsync使用所谓的“rsync算法”来使本地和远程两个主机 ...
- CSS选择器(通配符选择器、标签选择器、类选择器、id选择器、群组选择器、后代选择器、子元素选择器和相邻元素选择器)
通配符选择器 * 与任何元素匹配 派生选择器: 后代选择器(包含选择器):后代选择器可以选择作为元素后代的元素 A B 对A元素中的B元素应用样式 后代选择器中两个元素间的层次间隔可以是无 ...
- Linux--环境变量配置文件
Linux系统中环境变量配置文件分为两类: 全局环境变量配置文件 /etc/profile 用户环境变量配置文件 ~/.bash_profile . ~/.bash_login ~/.profile ...
- java 获取视频时间
//先将视频保存到项目生成临时文件,获取时长后删除临时文件 // 使用fastdfs进行文件上传 @RequestMapping("/uploadVideoToFast") @Re ...
- python3 之configparser 模块
configparser 简介 configparser 是 Pyhton 标准库中用来解析配置文件的模块,并且内置方法和字典非常接近[db]db_count = 31 = passwd2 = dat ...
- JavaWeb【四、JSP基础语法】
简介 JSP--Java Server Pages,根本是一个简化的Servlet设计,实现了在Java中使用HTML标签. 特点 跨平台,安全性好,大型站点开发,企业级Web应用,大数据. 对比: ...
- Maxwell平滑升级流程
1. 同步配置文件 copy之前的配置文件 2 关掉监控程序 如果有的话 3 kill掉之前的maxwell程序 4 查询已经读取到的position位置,然后重启服务 ...
- 第十四章·Kibana深入-Timelion画图实现系统监控
什么是Timelion? Timelion使你可以轻松获得以下问题的答案: 1)随着时间的推移,每个唯一的用户会查看多少个页面?2)这个星期五和上周五之间的交通量有什么不同?3)今天有多少日本人口来到 ...
- stm32定时器计数功能
stm32的外部时钟源模式2和外部时钟源模式1都可以用来实现计数功能,他们的区别是什么呢? 以上2种模式对应不同的管脚输入: 外部时钟源模式2 <-->TIMx_ETR 外部时钟源模式1 ...
- celery:强大的定时任务模块
什么是celery 还是一个老生常谈的话题,假设用户注册,首先注册信息入库,然后要调用验证码服务接口,然后根据手机号发送验证码,最后再返回响应给浏览器.但显然调用接口.发送验证码之后成功再给浏览器响应 ...