上帝视角一文理解JavaScript原型和原型链
2021-03-18 21:26
标签:bool 原因 实验 正式 模版 代码 strong 讲解 class 本文呆鹅原创,原文地址:https://juejin.im/user/307518987058686/posts 本文将从 阅读本文前可以思考下面三个问题: 大家接触原型和原型链时应该都看到过下面这张图。刚开始了解的时候,看到这个图大都不太明白,甚至一脸懵,这里先留个坑。 先祭图,让暴风雨来得更猛烈些! 下面开始讲解JS世界是如何一步步诞生的,看完你也就完全明白这张神图啦。 起初,上帝JS掌控的世界什么都没有。 现在我们要造点儿东西出来。但是没有原料怎么办? JavaScript中的1号对象产生了,不妨把它叫做机器1号。 刚开始造物,上帝当然想继续下去啦,既然已经有了一个始祖级的机器,剩下就好办了,因为一生二,二生三,三生万物嘛。 不过上帝很懒,他不想一个一个地亲手制造对象。于是他做了一台能够制造新对象的东西: 他给这个东西起了一个名字:Object。 但是这个Object制造对象时候,需要有一个模版,现在只有机器1号,它就取了机器1号当模版。图中的 如何启动制造呢?通过 把这个过程写成代码就是: 轰轰烈烈的造物运动开始了…… 有一天,上帝JS去看了上帝Java造的世界,发现上帝Java的世界好精彩,可不仅仅有Object对象,还有String对象、Number对象、Boolean对象等等。 于是上帝就思考了:那我可以多让机器造一些对象啊。 但是上帝觉得把这些工作都交给机器1号的话,机器1号太累了,不如让机器1号造一个机器2号来做这些工作。 重点说明下“这些工作”指的是:总体负责制造所有的对象,包含Object、String、Number、Boolean、Array,甚至还有之后的Function。当然它只是负责制造,并不一定会亲手去制造对象,可以通过制造对应的机器来帮助它制造对象 于是就有了机器2号: (注: 可能有的小伙伴注意到啦, 接下来,既然机器2号是由机器1号造出来的,而 但是Object有自己的模板:机器1号。而 其实机器2号在创建它们的时候并不是直接创建它们的,而是先创建了对应对象的机器作为模板,然后再由各自的机器来创建它们。 具体我画了String相关的图(其他Number、Boolean、Array等都是同一个道理的): 这样,这张图显示了JS世界中那些最基本的机器本身的原型链,以及它们的模板对象的原型链。 上帝看着越来越丰富的世界非常高兴,但是总感觉缺点什么? 一个声音说:世界缺少活力呀 上帝给这个新对象的起了个名字叫:Funciton 于是,Function对象就出现了 让我们来观察一下Function对象: 于是我们得到了Function的一个非常特别的性质: 于是JavaScript的世界的变成了下面的样子: 到现在我们能明白啦: 自从有了Function,世界就越来越有活力了,有什么事需要做,用new Function()造个新Function来做就行了。 但是刚造出来的Function机器很难用,用法就像下面这个: 你想要造一个Function,无论是输入的内容(参数)还是要做的事情(函数体)都得弄成字符串,才能成功造出来。 上帝用起来难受啊,他就改装了一下这个Function,给他来了个语法糖 (注:上面两段代码是完全等价的。) 现在造一个新的Function就舒服多啦! 以造 Function这个对象比较特殊,它new出来后,就是一个全新的对象了, 既然都是对象,当然 咱们称 当然既然是机器,所以 虽然机器2号制造了各种各样的机器,但是因为机器2号是由机器1号制造的,所以这些被制造的机器所属权还是归于机器1号的,毕竟机器1号是始祖级的。 而且这个 听起来好像有点绕,咱们看看图就明白啦 上图中: 现在我们就能完全理解并完整的画出原型和原型链的关系图啦: 其实可以被用来 为了清晰一些,上图用 现在这张图就是完整的原型和原型链的关系图啦 用正式的语言总结一下就是: 子类的__proto__属性,表示构造函数的继承,总是指向父类。 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。 现在我们再看这张神图: 是不是很简单啦,不过就是把咱们画的图向右旋转了90°。 而且仔细看一遍,咱们的关系图包含的更加的全面。 填坑完毕。下篇文章我会以此为延伸,从底层讲解JavaScript的this,看完你会彻底理解this为何物,关注我 ?? 点个赞支持我吧 ?? 上帝视角一文理解JavaScript原型和原型链 标签:bool 原因 实验 正式 模版 代码 strong 讲解 class 原文地址:https://www.cnblogs.com/piaobodewu/p/13795077.html前言
上帝角度
讲解JS的世界,在这个过程中,大家就能完全理解JS的原型和原型链是什么,之后还会基于原型和原型链知识拓展一些相关知识。
经典图
无中生有
上帝JS说:没有东西本身也是一种东西啊,于是就有了null
:
有一个声音说:现在不是有null
了嘛?
上帝说:那就无中生有吧!
这个机器1号可不得了,它是JS世界的第一个对象,它是真正的万物始祖。它拥有的性质,是所有的对象都有的。__proto__
是什么呢?是“生”的意思,或者换成专业点的叫法“继承”。有中生有
prototype
就代表模板对象。new
命令。你按下“new”按钮,新的对象就造出来了。var obj = new Object();
有生万物
__proto__
写起来麻烦,我们之后用[p]
来代替)Object
也指向了机器2号,这是因为机器2号是负责造对象的,当然也负责造Object
对象啦。String、Number、Boolean、Array
这些对象是由机器2号造出来的,所以它们其实和Object
一样,也自带了new
命令:你按下“new”按钮,新的对象就造出来了。String、Number、Boolean、Array
它们有模板吗?
机器2号
先制造了机器String号
,然后由机器String号
来制造String,机器2号
只负责总体控制prototype
来连接。如:对于String,机器2号
和String
通过prototype
连接万物缺活力
上帝说:那就造一个能让世界动起来的对象
但是这个制造Function的工作交给谁好呢,让世界动起来当然是非常重要的,那就交给机器2号吧,由机器2号亲手负责Function的制造
prototype
相连__proto__
相连Function.__proto__ === Function.prototype
世界动起来
let Foo = new Function("name", "console.log(name)");
Foo(‘dellyoung‘); // 控制台打印出:dellyoung
function Foo(name) {
console.log(name);
}
Foo(‘dellyoung‘); // 控制台打印出:dellyoung
Foo()
为例,于是JavaScript的世界的变成了下面的样子:function Foo()
(注意:它等价于 let Foo = new Function()
)和Object
、String
、Number
等这些对象一样,都是对象。function Foo()
也是由机器2号来控制制造的,但是机器2号很忙,它没有精力直接制造function Foo()
,机器2号是通过制造出一个制造function Foo()的机器
来制造function Foo()
。制造function Foo()的机器
为机器Foo()号
机器Foo()号
也是由机器1号
控制的,原因上文讲过:
function Foo()
对象制造出来后,它既然是对象,所以它和Object、String、Number等对象一样,可以通过new Foo()
制造出新的对象,模板就是用的机器Foo()号
。
Object.prototype
Function.prototype
String.prototype
Foo.prototype
__proto__
回到现实
new
的对象或函数,我们都可以称之为构造函数,每个构造函数都和它的机器(也就是XXX.prototype
)通过constructor
相连,我们来画出构造函数和它们的constructor
:
[con]
表示constructor
看完两件事
文章标题:上帝视角一文理解JavaScript原型和原型链
文章链接:http://soscw.com/index.php/essay/65944.html