JavaScript(6)--- 原型链
原型链
再上一篇有简单讲过原型:JavaScript(5)--- 面向对象 + 原型
讲原型链知识之前,先说几个重要的结论。
1、原型链就是 对象的__proto__所连接的链状结构
2、prototype 属性是函数独有的
3、__proto__ 属性是对象独有的,实例原型(Object.prototype)也是对象,所以也会有__proto__属性
下面我们一步一步来讲解原型链
一、prototype属性
1、构造函数创建对象
我们先使用构造函数创建一个对象:
function Person() {
}
var p = new Person();
p.name = 'xiaoxiao';
console.log(p.name); //xiaoxiao
2、 prototype属性
概念 它是 函数独有的属性,它从一个函数指向另一个对象,代表这个对象是这个函数的原型对象,这个对象也是当前函数所创建的实例的原型对象。
prototype设计之初就是为了实现继承,让构造函数创建的所有实例,都能够共享这个原型属性和方法。
有了prototype我们不需要为每一个实例创建重复的属性方法,而是将属性方法创建在构造函数的原型对象上(prototype)。那些不需要共享的才创建在构造函数中。
示例
function Person(){
}
Person.prototype.age=18; //原型属性
var p1 = new Person();
var p2 = new Person();
console.log(p1.age);//18
console.log(p2.age);//18
思考 这个函数的 prototype 属性到底指向的是什么呢?
其实,函数的 prototype 属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型 。
思考 那么什么是原型呢?
每一个 JavaScript 对象 (null 除外 ) 在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型 ” 继承 ” 属性。
这里p1和p2就是实例对象,而Person.prototype就是它们的原型对象。p1和p2可以去继承原型对象的方法和属性。
让我们用一张图表示构造函数和实例原型之间的关系:

二、__proto__属性
概念
__proto__属性是对象(包括函数,函数也是对象)独有的。__proto__属性是从一个对象指向另一个对象,该属性指向的就是该对象的原型对象(也可以理解为父对象)。
示例
function Person(){
}
var p = new Person();
console.log(p.__proto__ === Person.prototype);//true
更新下关系图

__proto__通常称为隐式原型,prototype为显示原型,那我们可以说一个对象的隐式原型指向了该对象的构造函数的显示原型。那么我们在显示原型上定义的属性方法,
通过隐式原型传递给了构造函数的实例。这样一来实例就能很容易的访问到构造函数原型上的方法和属性了。
三、constructor属性
概念
constructor是对象才有的属性,它是从一个对象指向一个函数的。指向的函数就是该对象的构造函数。
注意了 实例原型也是对象,所以也会有constructor属性,我们来验证一下
function Person(){
}
console.log(Person === Person.prototype.constructor);//true
console.log(person.constructor); // ƒ Person(){}
再更新下关系图

总结 通过上面的演示说明,我们可以得出
function Person(){
}
var person = new Person();
console.log(person.__proto__ === Person.prototype);//true
console.log(Person === Person.prototype.constructor);//true
了解了构造函数、实例原型、和实例之间的关系,接下来我们讲讲实例和原型的关系
四、实例与原型
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。
示例
function Person(){
}
var person = new Person();
Person.prototype.name='张三';
person.name='李四';
console.log(person.name);//李四
delete person.name;
console.log(person.name);//张三
在这个例子中,我们设置了 person 的 name 属性,所以我们可以读取到为 ’李四’ ,当我们删除了 person 的 name 属性时,读取 person.name ,从 person 中找不到
就会从 person 的原型中查找,name为 ’张三’ 。但是万一Person.prototype原型中还没有找到呢?那会到原型的原型去查找。也就是Object.prototype
示例
function Person(){
}
var person = new Person();
Person.prototype.name='李四';
person.name='张三';
console.log(person.name);//张三
delete person.name;
console.log(person.name);//李四
Object.prototype.name='obj';
delete Person.prototype.name;
console.log(person.name);//obj
所以原型对象是通过 Object 构造函数生成的,结合之前所讲 , 实例的 _proto_ 指向构造函数的 prototype, 所
再更新下关系图

五、原型链
那 Object.prototypey也是对象,那它也应该会有原型。只不过有是有,只是为null , 所以查到 Object.prototype 就可以停止查找了 。
所以最后一张关系图就是

总结 图中由相互关联的原型组成的链状结构就是原型链,也就是红色的这条线。
参考
1、JavaScript深入之从原型到原型链 非常感谢
别人骂我胖,我会生气,因为我心里承认了我胖。别人说我矮,我就会觉得好笑,因为我心里知道我不可能矮。这就是我们为什么会对别人的攻击生气。
攻我盾者,乃我内心之矛(3)。
JavaScript(6)--- 原型链的更多相关文章
- Javascript的原型链图
90%的前端或者js程序员或者老师们对Javascript懂得不比这个多 给手机看的 但是这个图里的所有褐色单向箭头链就是Javascript的原型链(颜色标注对理解js原型链很关键) 这图中的各个_ ...
- javaScript系列 [04]-javaScript的原型链
[04]-javaScript的原型链 本文旨在花很少的篇幅讲清楚JavaScript语言中的原型链结构,很多朋友认为JavaScript中的原型链复杂难懂,其实不然,它们就像树上的一串猴子. 1.1 ...
- JavaScript的原型链继承__propt__、prototype、constructor的理解、以及他们之间相互的关系。
回想自己已经工作了有一段时间了,但是自己对JavaScript的原型链.和继承的理解能力没有到位,最近他们彻底的整理并且复习了一遍. 本案例中部分文案来自网络和书籍,如有侵权请联系我,我只是把我的理解 ...
- javascript prototype原型链的原理
javascript prototype原型链的原理 说到prototype,就不得不先说下new的过程. 我们先看看这样一段代码: <script type="text/javasc ...
- javaScript(原型链)
在了解javaScript的原型链之前,我们得先来看一下原型是什么. 在javaScript中,所有的函数都会有着一个特别属性:prototype(显示原型属性):当我们运行如下代码时: functi ...
- 理解JavaScript的原型链
1. 什么是对象 在JavaScript中,对象是属性的无序集合,每个属性存放一个原始值.对象或函数. 1.1 创建对象 在JavaScript中创建对象的两种方法: ① 字面上: var myObj ...
- JavaScript扩展原型链浅析
前言 上文对原型和原型链做了一些简单的概念介绍和解析,本文将浅析一些原型链的扩展. javaScript原型和原型链 http://lewyon.xyz/prototype.html 扩展原型链 使用 ...
- javascript的原型链那些事
如果你对javascript的原型链还有任何疑问,请看这篇文章 进入主题 前言 原型链的规则不百分百适用于所有情况 显式原型:prototype,是一个对象{} 隐式原型:__proto__,是一个对 ...
- 深入浅出JavaScript之原型链&继承
Javascript语言的继承机制,它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instanc ...
- javascript继承--原型链的 继承
作者的话:原型链是JavaScript中相当重要的一个知识点,这里我使用了函数结构图,来帮助我更好的理解 /* 原型链继承方式: 通过改变一个对象的原型对象的指向来继承另一个对象 原理: 我们知道,一 ...
随机推荐
- 工厂方法FactoryMethod 初步学习笔记
一,意图 定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. 二,别名 虚构造器 Virtual Constructor 三,适用性 当一个类不知道它 ...
- python后端面试第一部分:python基础--长期维护
1. 为什么学习Python? 2. 通过什么途径学习的Python? 3. Python和Java.PHP.C.C#.C++等其他语言的对比? 4. 简述解释型和编译型编程语言? https:/ ...
- 牛客-小w的a=b问题
题目传送门 sol1:老实做,预处理出所有2到1e5的素数,对所有数进行分解质因数,然后对比因子个数.感觉有点卡常,用了快读然后多次优化之后才过的,map也用上了. 素数筛,快速分解质因数 #incl ...
- 蓝桥杯-PREV45-图形排版
这是2017年蓝桥杯C组C++的压轴题,拿到之后没什么想法.但是蓝桥杯有部分分.所以直接敲了个大暴力提交上去过了一半的数据.后来想到了DP,但是没能实现出来,感觉还是有问题的.后来看了解题视频发现是预 ...
- 求求你,下次面试别再问我什么是 Spring AOP 和代理了!
https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9403056301388627935% ...
- 荼菜的iOS笔记--UIView的几个Block动画
前言:我的第一篇文章荼菜的iOS笔记–Core Animation 核心动画算是比较详细讲了核心动画的用法,但是如你上篇看到的,有时我们只是想实现一些很小的动画,这时再用coreAnimation就会 ...
- Qt QString 与 const char* 类型的转换
QString DATA; std::string str = DATA.toStdString(); const char* ch = str.c_str();
- struts2学习笔记之十四:使用注解配置Action(不是和spring集成使用)
Struts2支持使用注解配置Action,减少配置文件的配置 Struts2如果要支持注解配置Action,需要插件的支持,导入插件struts2-convention-plugin-2.1.8.1 ...
- openpyxl操作excel表格
1.openpyxl 只支持打开.xlsx格式,其他excel类库基本也是 2.不能这里的工作面板直接右键新建表格,必须到文件夹下面去新建,可以把在别的目录新建的表格直接复制到当前目录下 3.从表格中 ...
- Navicat导入导出数据表
当我们对mysql数据库进行了误操作,造成某个数据表中的部分数据丢失时,肯定就要利用备份的数据库,对丢失部分的数据进行导出.导入操作了.Navicat工具正好给我们提供了一个数据表的导入导出功能. 1 ...