一张图搞懂 Javascript 中的原型链、prototype、__proto__的关系 转载加自己的总结
1. JavaScript内置对象
所谓的内置对象 指的是:JavaScript本身就自己有的对象 可以直接拿来就用。例如Array String 等等。JavaScript一共有12内置对象
其中10个函数类型( String,Number,Boolean,Array,Function,Date,RegExp,Error,Object,Event )函数类型 有 __proto__和 prototype 属性
2个对象类型(Math,JSON) 对象类型只有__proto__属性。
下面有一张图片 由苏仔提供。

2. 感性认识JS里的“德罗斯特效应”之原型链
打开浏览器的控制面板,随便输入一个JS内置的构造器函数,比如Array,控制台输出的是一个名为Array的函数体,这好像并没有什么稀奇的,但是,当你接着输入Array.prototype,控制面板输出了一堆我们经常用到的Array构造器的方法,把目光转移到最下方,有一个叫__proto__的属性,好奇的点开。列表列出的不是Object构造器的方法么,里边有我们非常熟悉的hasOwnProperty还有toString等方法。如果Array是构造器,那么控制面板输出的Array.prototype的所有属性中constructor又是什么构造器?点开看看,之后就像身处德罗斯特效应中一样,__proto__和constructor,还有Array构造器中常用的方法名不断的出现,一层套一层,一层层展开,没有尽头。。。
怎么证明 你是你?
拿Array举例,Array.prototype中有一个constructor属性,这个属性的值就是Array构造器自己。 所以我在console里面测试
(每一个构造函数都有)

2、“遗传进化链__proto__”,怎么证明一切皆对象?
所有的JS内置构造器都本是对象。可是从什么线索开始向过去前进呢,原型链(我给他起了一个名字叫遗传进化链)就是突破口。所有JS构造器(当然不止构造器有)都有一个__proto__属性,这是原型链指针,指向遗传进化成它的“那个”。它“遗传”了“那个”的特性,而有进化出了它自有的特性。

这里Array 内置对象 且是函数类型。所以Array有__proto__属性 指向的是函数类型 (function(){})。所以当我们在输出Array.__proto__.proto__;就会返回对象类型(Object{}).但是再向上就null。因为Object就是父类了。所有的继承自Object。
JS内置构造器其中之一的Array原本就是一个函数,而这个函数就是Function的prototype,所以Function.prototype有的方法,JS内置构造器都有,比如call()、apply()、bind()等(其实我们自定义的函数也是继承自Function.prototype,所以我们自己也可以定义构造器)。而Function.prototype的进化链指针又指向了Object.prototype。
3、怎么证明到头来一切都是空?

4、怎么证明所有JS内置构造器和自定义函数都是Function构造器的原型(prototype)。
10个函数类型构造器的进化链指针__proto__指向Function构造器的原型.

这里需要注意所有构造器的prototype都是对象(object)类型,只有Function.prototype是函数(function)类型,这是为了保证函数构造器们的__proto__指向的都是函数。
3. JSON和Math
JS内置的构造器函数都可以使用new关键字实例化一个对象,我们称实例化后的这个对象就是某某构造器的一个实例。就像我们每一个“人”都是“人类”这个构造器函数的一个实例。

我们试试JSON 和Math 能不能实例化对象。

不可以。JSON和Math不是构造器函数,他们是普通的对象。
只有构造器函数才能使用new 关键字实例化一个对象,而JSON和Math已经是对象了,所以我们可以不用实例化直接使用JSON和Math中的属性和方法~~(我们实例化的目就是想用实例化后的对象里的属性和方法,那么既然JSON和Math已经是对象了,就省去实例化的操作 直接使用静态方法。
所以JSON和Math不属于10个构造器函数,但他们12个共同属于Javascript的内置对象。
4. __proto__进化链指针设计为什么如此重要
javascript中为什么会有__proto__原型链的设计。
先实例化一个String对象并将其赋值给str这个变量,然后我们输出这个str

从str输出的内容来看,str有四个属性,分别是0、1、2、length。
但是 str.charAt(0); // l
str里面没有charAt()方法 但是没有报错。这是因为str的进化链上存在这个属性方法,那么charAt()这个方法在进化链的那个节点上呢。

原来String.prototype拥有charAt这个方法,而str的__proto__指针指向String.prototype。str.__proto__.__proto__指向的对象所拥有的属性str也都可以直接用
看到str.__proto__.__proto__指向的对象所拥有的属性中有一个hasOwnProperty属性方法了么,str可以直接使用这个属性方法 在验证之前先说下str.__proto__.__proto__指向了谁?指向的是Object的prototype属性。

Object.prototype.hasOwnProperty()属性方法用来检验一个对象是否自己拥有一个属性而非通过进化链__proto__继承来的属性。

对于Javascrip初学者,一时半会肯定还是搞不清楚,唯一的办法就是多看、多想、多练、多总结、多分享~,学习的本质无非就是这些。
一张图搞懂 Javascript 中的原型链、prototype、__proto__的关系 转载加自己的总结的更多相关文章
- 三张图搞懂JavaScript的原型对象与原型链
对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__proto__混淆,二来它们之间的各种指向实在有些复杂,其实市面上已经有非常多的文章在尝试说清楚,有一张 ...
- 一张图看懂JavaScript中数组的迭代方法:forEach、map、filter、reduce、every、some
好吧,竟然不能单发一张图,不够200字啊不够200字! 在<JavaScript高级程序设计>中,分门别类介绍了非常多数组方法,其中迭代方法里面有6种,这6种方法在实际项目有着非常广泛的作 ...
- 三张图搞懂JavaScript的原型对象与原型链 / js继承,各种继承的优缺点(原型链继承,组合继承,寄生组合继承)
摘自:https://www.cnblogs.com/shuiyi/p/5305435.html 对于新人来说,JavaScript的原型是一个很让人头疼的事情,一来prototype容易与__pro ...
- 一张图搞懂javascript原型链
js高级里面原型链对于新手来说并不友好,总的来说就是 任何函数都有自己的原型对象(prototype),任何实例对象都__proto__指向构造函数的原型 先来个最简单的原型三角关系 var fn = ...
- 来一轮带注释的demo,彻底搞懂javascript中的replace函数
javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用.最近和前端走的比较近,借此 ...
- 一张图搞懂Spring bean的完整生命周期
一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任何一个环节怎么操作bean的生成及修饰是非常有帮助的. ...
- [转帖]两张图看懂GDT、GDTR、LDT、LDTR的关系
两张图看懂GDT.GDTR.LDT.LDTR的关系 2018-06-09 18:13:53 Six_666A 阅读数 2044更多 分类专栏: 深入理解linux内核 转自:http://ju.o ...
- 图解JavaScript中的原型链
转自:http://www.jianshu.com/p/a81692ad5b5d typeof obj 和 obj instanceof Type 在JavaScript中,我们经常用typeof o ...
- 深入了解JavaScript中基于原型(prototype)的继承机制
原型 前言 继承是面向对象编程中相当重要的一个概念,它对帮助代码复用起到了很大的作用. 正文 Brendan Eich在创建JavaScript时,没有选择当时最流行的类继承机制,而是借鉴Self,用 ...
随机推荐
- Sybase datetime 时间转换格式 convert(varchar(10),字段名,转换格式)
convert(varchar(10),字段名,转换格式)sybase下convert函数第三个参数(时间格式)比如:1.select user_id,convert(varchar(10),dayt ...
- Android(性能)
■ 数据传输 对象和字节流之间的转换 为什么要转? 持久化(装逼说法,JVM非运行的场合),他进程(装逼说法,其他机器JVM,不同的JVM) Parcelable和Serializable 初衷: P ...
- Xcode使用xib拖线时出现: could not insert new outlet connection
解决方法: 1.在新建类的时候没有选择将这个类加入到对应的"Target"中. 2.重新将文件加入项目 操作步骤就是选中出问题的.m和.h文件,点删除键,然后选"Remo ...
- hdu2937
题目大意: 给出n求sn,中括号代表向下取整. 为了方便表述,我们令a = (3k+6)!,b = (3k+7),令c = (a+1)/b也就是式子中的前半部分,d = a/b也就是式子中的后半部分. ...
- 兄弟选择器 E + F
兄弟选择器在IE7下支持会有bug,特记于此 如果兄弟选择器有Html注释,兄弟选择器在IE7下会失效 代码如下 E + Fp + p{color:red} <p class="te ...
- mysql与java数据类型对应关系
- wordpress禁止调用官方Gravatar头像调用ssl头像链接提升加载速度
在主题中的functions.php文件末尾加上以下代码即可(外观>编辑>functions.php) //官方Gravatar头像调用ssl头像链接 function get_ssl_a ...
- Spring boot构建基于rest的Web服务
一.介绍:使用Spring Boot我们可以很容易的创建一个可独立运行的Rest web服务,其中内嵌tomact,我们只需“run”就可以查看效果了. Spring Boot利用Gradle或Mav ...
- Android学习笔记--Menu菜单的使用
实现选项菜单.上下文菜单,以及菜单内部的子菜单. 视图效果: MainActivity 选项菜单 选项菜单的子菜单 上下文菜单(按住按钮或者EditText弹出) 注意:上下文菜单如何弹出?在注册该菜 ...
- Adt 配置注释模板
点击Window->Preferences->Java->Code Style->Code Templates,如下图所示: 选中,点击右侧的Edit进行编辑.