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中相当重要的一个知识点,这里我使用了函数结构图,来帮助我更好的理解 /* 原型链继承方式: 通过改变一个对象的原型对象的指向来继承另一个对象 原理: 我们知道,一 ...
随机推荐
- C# 将多个DataTable添加到指定的DataSet中
DataSet ds = new DataSet();//创建数据集 DataTable dt1=new DataTable(); //表1 DataTable dt2 = new DataTable ...
- 1022 D进制的A+B (20 分)
题目:1022 D进制的A+B (20 分) 思路: 首先根据A.B的取值范围,可知A+B不过2^31,所以转换成进制数时的最长长度为31. 转换成进制的数存进数组,然后反向输出. 要注意和为0的情况 ...
- GCC与静态库、动态库
GCC 常用指令 1 man gcc gcc工作流程例如: gcc hello.c 1234567891011121314 //***第一步***gcc -E hello.c >hello.i ...
- JSP_EL的回顾
在 JSP 页面中,使用标签库代替传统的 Java 片段语言来实现页面的显示逻辑已经不是新技术了,然而,由自定义标签很容易造成重复定义和非标准的实现.鉴于此,出现了 JSTL ( JSP Standa ...
- Starting php-fpm [18-Jun-2019 12:56:59] NOTICE: PHP message: PHP Warning: Version warning提示报错解决
php-fpm在命令行重启时出现如下提示信息在终端上,虽然不影响使用,但是不够干净利落,参考了一篇国外博客得以解决,参考链接:https://community.centminmod.com/thre ...
- Java运行 Unsupported major.minor version 51.0 错误
今天写了简单的Java程序,运行的时候不知道为啥出现这个问题 happy@happy-HP-Compaq-dx7518-MT:~/Study/CrazyJava$ java FieldTest Exc ...
- ECMA5中定义的对象属性特性和方法
ECMA5规定了只有内部才有的特性,描述了属性的各种特征,这些特性用于实现JavaScript引擎,因此在Js中不能直接访问他们.为了标识特性,我们一般会他们放入两对方括号中. ECMAScript中 ...
- 对话|首席研究员童欣:从长远看,AR的应用范围远比VR广泛
童欣博士现任微软亚洲研究院网络图形组首席研究员.1993年毕业于浙江大学计算机系,获工学学士学位:1996年获浙江大学计算机系硕士学位:1999年获清华大学计算机系博士学位,同年加入微软亚洲研究院. ...
- 《N诺机试指南》(八)日期、字符串、排序问题
1.日期问题: 输入: 例题: 代码: #include <stdio.h> #include <bits/stdc++.h> struct node{ int year, m ...
- sed 分组替换
将文件以help开头的句子前加# [root@localhost]# cat a.txthelp b helphelp1helphelp2help c help[root@localhost]# se ...