彻底深刻理解js原型链之prototype,proto以及constructor(二)

2020 年 11 月 20 日

彻底深刻理解js原型链之prototype,proto以及constructor(二)

前言


如果你能够啃下教程一并且吃透原型链的几个概念的话说明你在前端飞仙的路上又进了一小步···学习最怕的不是慢而是站!这篇教程主要目的对原型链概念进一步加深理解


巩固下教程一的知识


来看下面的例子:


var text=new String("我是文字");function Persion(name,job){    this.name=name;    this.job=job;}Persion.myName="lxm";Persion.prototype.sayName=function(){    alert(this.name);}var perison1=new Persion("lxm","20")
复制代码


思考:判断下列表达式返回的值:

(两分钟之内对八道的算及格,剩下的同学回头接着理解教程一,传送门在此 [http://0313.name/2017/01/13/prototype-proto-constructor.html])


perison1.__proto__===Persion.prototype;perison1.name===Persion.name;perison1.prototype.__proto__===Object.prototype;Persion.prototype.__proto__===Object.prototype;Persion.__proto__===Function.prototype;Persion.constructor===perison1;Function.__proto__===Object.prototype;Function.prototype.__proto__===Object.prototype;typeof Persion.prototype;typeof Function.prototype;
复制代码


原型链图


这个图绝对是网络上独一无二独一份,此乃小米飞升教程独家秘籍!因为博主在学习过程中发现对文字的理解和记忆远远不如一个图来的更深更直观,更加透彻,为了您更好的学习原型链,博主特意花了一上午的时间用 mermaid 绘制了这个原型链的关系图,而且通过这个图我们能够发现很多有意思的事情 为了关系图更加直观和清晰,隐去了一些引用线路,其中:


  • 圆形代表对象的名字

  • 方形代表属性名

  • 实线代表对象的分界

  • 虚线代表引用

  • 菱形代表基本值



  • 原型链是单链,只往一个方向流向,没有回路

  • 只有Function的 proto 指向自己的prototype,这也向我们解释了为什么Function.prototype类型是function

  • 我们通过 proto 只能获取到原型对象中的方法和属性,所以persion1通过原型链是获取不到Persion的myName属性,但是我们可以通过原型对象的constructor来获取或者修改Persion的属性(这点太给力了)


请注意,有时候这个方法也不好使,因为原型对象的constructor是可以改变的,不一定指向原型对象所在的函数对象


继续上面的例子:


persion1.__proto__.constructor.myName="我变了耶!";console.log(Persion.myName); //我变了耶
复制代码


  • 普通对象的 proto_ 一定指向创造它的函数对象的prototype

  • 原型对象的 proto 一定指向Object.prototype!

  • 通过图我们可以简单理解,拥有原型对象属性的对象是函数对象,否则为普通对象

  • 原型链是有开始和尽头的,开始于null,结束于普通对象

  • 所有的函数对象都是Function以new的方式创造出来了,包括Function自己且每个函数对象的 proto 都指向了Function.prototype

  • Object是所有对象的父类,我们也可以称之为基类,不过不要纠结于叫什么,因为我们通过图可以看到每一个对象(不管是原型对象还是普通对象还是函数对象)的通过原型链都可以引向Object.prototype


以上九条我称为原型链之九句真言(不要太在意名字,我自己随便起的 ~)


意外收获:this.name和this.job难道不应该在Persion中也有一份吗?无数个日夜,愚笨的博主对this的用法都不甚了解,直到我画出了这种图,我彻底明白了this的含义,就是谁运行包含this的这个函数,this就把挂在它身上的包袱(属性)甩给谁! 看到了吗,persion1调用了Persion,那么自然多了2个属性,但是注意,name跟job并不是Persion的属性!!


思考:图中没有画出 Object. proto 的指向,请问他指向哪?(请只依据九句真言解答)


思考题解答


思考:判断下列表达式返回的值:


perison1.__proto__===Persion.prototype;
复制代码


首先判断perison1是通过new方式被Persion创造出来的,依据九句真言第4条得出 :true


perison1.name===Persion.name;
复制代码


通过关系图可以看到不相等,我已经在意外收获中解答了,答案为:false


perison1.prototype.__proto__===Object.prototype;
复制代码


只看图可以看到perison1没有prototype,是普通对象所以答案为:js报错~~


Persion.prototype.__proto__===Object.prototype;
复制代码


参考九句真言第5条:答案为:true


Persion.__proto__===Function.prototype;
复制代码


Persion为函数对象,参考九句真言第8条,答案为:true


Persion.constructor===perison1;
复制代码


Persion是由Function创造出来的所以Persion.constructor指向Function,答案为:false


Function.__proto__===Object.prototype;
复制代码


Function我们已经反复强调是由自身创造所以Function. proto ===Function.prototype;,答案为:false


Function.prototype.__proto__===Object.prototype;
复制代码


根据九句真言第5条,答案为:true


typeof Persion.prototype;
复制代码


答案为:object


typeof Function.prototype;
复制代码


答案为:function,注意这个是比较特殊的原型对象


思考:图中没有画出 Object.proto 的指向,请问他指向哪?(请只依据九句真言解答)


下面来分步解答


  • Object属于函数对象

  • 依据九句真言第八条得出函数对象的 proto 都指向了Function.prototype

  • 所以Object. proto ===Function.prototype


这一点是不太好理解的,是 Function 创造了 Object,然后 Object 创造了 Function 的原型对象 prototype 所以就有了


Object.__proto__===Function.prototypeFunction.prototype.__proto__===Object.prototype
复制代码


不要太纠结于此,只要理解就好


结束语


好了,原型链的概念原理通过这 2 篇教程我相信大家已经滚瓜烂熟了!下面的教程,我们会着重研究下原型链在实际的应用!


本文转载自宜信技术学院。


原文链接


彻底深刻理解js原型链之prototype,proto以及constructor(二)


2020 年 11 月 20 日 10:10539

评论

发布
暂无评论
发现更多内容

Flutter引擎源码解读-Flutter是如何在iOS上运行起来的

稻子

flutter ios 移动应用 跨平台 dart

JAVA中Base64加密与解密

Howe

Java base64 加密解密

MyBatis核心功能介绍

Java收录阁

mybatis

动态规划问题的思路和技巧

Kenn

算法 动态规划

20 大类,100+ 网络副业兼职平台汇总推荐

一尘观世界

程序员 自由职业 副业 赚钱

记录自有意义

彭宏豪95

人生 写作 感悟 记录

Nacos 1.1.4 与微服务的实践经验记录

itfinally

Java 微服务 nacos

缓存的五种设计模式

Rayjun

缓存

Redis学习笔记(概述)

编程随想曲

redis

Boyer-Moore 算法

Kenn

算法 数组 Boyer-Moore

深入浅出逻辑组合电路(1)

顾洋琛

学习笔记 电子技术 大学生日常

Java新技术:文字块

范学雷

Java 编程语言

职场“35岁现象”:焦虑 or 出路?是时候说出真相了!

狂师

职场 成长 软件测试 测试 软件开发

如何梳理画出牛逼的、高大上的架构图?

狂师

程序员 企业架构 开发者 软件测试 软件开发

​成功的人,都是 “狠角色”

非著名程序员

程序员 提升认知 成功学 自律

Kafka系列第1篇:Kafka是什么?它能干什么?

z小赵

大数据 kafka 推荐 实时计算

太极宗师与华晨宇

伯薇

水平思考力 电视剧 综艺节目 歌手

游戏夜读 | 2020周记(4.3-4.10)

game1night

制作Unknown Pleasures效果图的3种方法

张云金_GISer

设计 T恤 GIS 地图

为AndroidApk添加系统级签名

Howe

Java android

为什么每个软件人都要懂点系统架构?

刘华Kenneth

架构 DevOps 高可用 敏捷 高并发

KubeFATE: 用云原生技术赋能联邦学习(二)

亨利笔记

Kubernetes 云原生 k8s FATE KUBEFATE

如何优雅的接收正在运行古董代码?

冰临深渊

项目管理 架构

聊聊测试工程师的价值

鱼贩

软件测试 质量 测试工程师产出 测试的价值

Java并发编程系列——锁顺序

孙苏勇

Java Java并发 并发编程 多线程

Phantomjs、Selenium之后浪Puppeteer

飞哥

程序员陪娃漫画系列——上学路上

孙苏勇

程序员 生活 程序员人生 陪伴 漫画

Spring中的测试类~简洁方便

程序员的时光

spring

周日福利来了

志学Python

Python 福利 python教程 python视频教程

Kafka系列第2篇:安装测试

z小赵

大数据 kafka 推荐 实时计算

Kafka系列第4篇:消息发送时,网络“偷偷”帮忙做的那点事儿

z小赵

kafka 推荐 实时计算

AI如何在普惠金融的探索中发挥作用?

AI如何在普惠金融的探索中发挥作用?

彻底深刻理解js原型链之prototype,proto以及constructor(二)-InfoQ