面不面试的,你都得懂原型和原型链

2023-01-06 0 1,023

转自:提前布局 – 亚历克斯陈

序言

千万别为的是复试而去背题,匆忙的,不但学不进来,背完了几天后布季忘掉。

面不面试的,你都得懂原型和原型链

你可能会说,“没配套措施,这并非为的是能找份组织工作嘛!”。我想说的是,“那你没已经开始找组织工作的这时候,咋不努力学习呢。”

好了,前述扯的那些,原意是让他们千万别做珍藏者,千万别把好文珍藏了,就放到电话簿里吃灰!

上面为他们单纯阐释我对蓝本和蓝本链的认知,若是真的有说的不对的地方性,还望间接把网页停用了,别在我这首诗上竭尽全力无用。(逃)

面不面试的,你都得懂原型和原型链

五个准则

他们先来介绍上面提及类别的五个准则:

1、提及类别,都具备第一类优点,方可民主自由扩充优点。

2、提及类别,都有两个显式蓝本 __proto__ 优点,优点值是两个一般的第一类。

3、提及类别,显式蓝本__proto__ 的优点值指向它的构造函数的显式蓝本 prototype 优点值。

4、当你试图得到两个第一类的某个优点时,如果这个第一类本身没有这个优点,那么它会去它的显式蓝本 __proto__(也就是它的构造函数的显式蓝本prototype)中寻找。

提及类别:Object、Array、Function、Date、RegExp。这里我姑且称 proto 为显式蓝本,没有官方中文叫法,他们都瞎叫居多。

下面他们逐一验证上面几个准则,就会慢慢地认知蓝本和蓝本链。

准则一

提及类别,都具备第一类优点,方可民主自由扩充优点:

const obj = {} const arr = [] const fn = function () {} obj.a =1 arr.a = 1 fn.a = 1 console.log(obj.a) // 1 console.log(arr.a) // 1 console.log(fn.a) // 1 复制代码

这个准则应该比较好认知,Date 和 RegExp 也一样,就不赘述了。

准则二

提及类别,都有两个显式蓝本 __proto__ 优点,优点值是两个一般的第一类:

const obj = {}; constarr = [];const fn = function() {} console.log(obj.__proto__, obj.__proto__); console.log(arr.__proto__, arr.__proto__);console.log(fn.__proto__, fn.__proto__); 复制代码
面不面试的,你都得懂原型和原型链

准则三

提及类别,显式蓝本 __proto__ 的优点值指向它的构造函数的显式蓝本 prototype 优点值:

const obj = {}; const arr = []; const fn = function() {} obj.__proto__ == Object.prototype // true arr.__proto__ === Array.prototype // true fn.__proto__ == Function.prototype // true 复制代码

准则四

当你试图得到两个第一类的某个优点时,如果这个第一类本身没有这个优点,那么它会去它的显式蓝本__proto__(也是它的构造函数的显式蓝本 prototype)中寻找:

const obj = { a:1} obj.toString// ƒ toString() { [native code] } 复制代码

首先, obj 第一类并没有 toStringtoString 优点,是遵循了第四条准则,从它的构造函数 Objectprototype

两个特例

我试图想推翻上面的准则,看上面这段代码:

function Person(name{   this.name = name   return this // 其实这行可以不写,默认返回 this 第一类 } var nick = new Person(“nick”) nick.toString // ƒ toString() { [native code] } 复制代码

按理说, nickPerson 构造函数生成的实例,而 Personprototype 并没有 toString 方法,那么为什么, nicktoString 方法?

这里就引出 蓝本链 的概念了, nick实例先从自身出发检讨自己,发现并没有toString 方法。找不到,就往上走,找 Person 构造函数的 prototype 优点,还是没找到。构造函数的 prototype也是两个第一类嘛,那第一类的构造函数是 Object,所以就找到了Object.prototype 下的 toString 方法。

面不面试的,你都得懂原型和原型链

前述寻找的过程就形成了蓝本链的概念,我认知的蓝本链是这样两个过程。也不知道哪个人说过一句,JavaScript 里万物皆第一类。从前述情况看来,好像是这么个理。

一张图片

用图片描述蓝本链:

面不面试的,你都得懂原型和原型链

最后两个 null,设计上是为的是避免死循环而设置的, Object.prototype 的显式蓝本指向 null

两个方法

instanceof运算符用于测试构造函数的prototype 优点是否出现在第一类蓝本链中的任何位置。instanceof 的简易手写版,如下所示:

// 变量R的蓝本 存在于 变量L的蓝本链上 function instance_of (L, R{       // 验证如果为基本数据类别,就间接返回 false   const baseType = [stringnumberbooleanundefinedsymbol]   if(baseType.includes(typeof(L))) { return false }   let RP = R.prototype;  // 取 R 的显示蓝本   L = L.__proto__; // 取 L 的显式蓝本   while (true) {     if (L === null) { // 找到最顶层       return false;     }     if (L === RP) { // 严格相等       return true;     }     L = L.__proto__;// 没找到竭尽全力向上一层蓝本链查找   } } 复制代码

他们再来看上面这段代码:

function Foo(name{   this.name = name; }var f = new Foo(nick) f instanceof Foo // trueinstanceof Object // true 复制代码

前述代码判断流程大致如下:

1、 f instanceof Foof 的显式蓝本 __proto__Foo.prototype ,是相等的,所以返回 true

2、 f instanceof Objectf 的显式蓝本 __proto__ ,和 Object.prototype 不等,所以竭尽全力往上走。f 的显式蓝本 __proto__ 指向 Foo.prototype ,所以竭尽全力用 Foo.prototype.__proto__ 去对比 Object.prototype,这会儿就相等了,因为Foo.prototype 是两个一般的第一类。

再一次验证万物皆第一类。。。。

总结

通过五个优点、两个例子、一张图片、两个方法,他们应该对蓝本和蓝本链的关系有了大概的认知。我的认知是,蓝本链就是两个过程,蓝本是蓝本链这个过程中的两个单位,贯穿整个蓝本链。就好像你要是看完了不点个赞,我可以顺着网线找到你。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务