【JavaScript】原型对象 => 原型链的深入浅出解读

在这里插入图片描述

在这里插入图片描述

先知概念:

在了解原型与原型链之前,我们应该要先明确以下几个概念:

1. 在 JS中 所有的普通对象 都是 通过 new 一个函数来创建的
2. 在 JS中 所有的函数 本质上也是一个对象,它是通过 new Function产生的

诠释【1】

我们平时所写的 let a = {};,其实本质上 相当于 let a = new Object(); 我们所简写的 {} 算是一个语法糖,同理 let b = [];,相当于 let b = new Array();,我们简写的 [] 也是一个语法糖

let a = {}; //等同 new Object()
console.log(a);

let b = []; //等同 new Array()
console.log(b);

案例说明:当我们自定义一个函数,并通过 new 来创建一个对象。

问:下面 new test()是否会产生一个对象,并且是哪个构造函数的对象?

const test = function () {
  return {};
};
let obj = new test();
console.log(obj);      //  Object  

首先 通过new 一个函数肯定会产生一个对象。因为我们说过对象也一定是通过 new 一个函数产生的。

在这一段代码中 有的小伙伴可能会认为这就是 new test 所以 构造函数 是test,其实非也。因为,如果一个函数中的返回值 是一个对象的话,那么我们通过 new 得到的就是它的返回值本身,此处的函数返回值是一个{},相当于是 new Object(),就是说 obj 等于 new Object() 产生的 一个 普通的 Object 对象
在这里插入图片描述

—__—同理反之:
如果此处的函数返回值是一个非对象 的值或者 没有返回值,那么得到的就是当前构造函数的对象

const test = function () {
  //return 123;
};
let obj = new test();
console.log(obj);      //  test

在这里插入图片描述

诠释【2】 ( 在 JS中 所有的函数 本质上也是一个对象,它是通过 new Function产生的)

我们平时写法定义的函数 function fn() {},其实本质上 相当于 let fn = new Function(); 我们定义函数的 function 关键字,其实也属于一个语法糖,再结合我们上面讲的,只要 new 一个函数,一定会产生一个对象,因为 函数也是通过 new得来的,所以说函数本质上也是一个对象

从这里开始,我们就可以区分出在 JS 中,对象可以被分为 普通对象函数对象。再说的通俗一点就是,函数本质上既是一个函数也是一个对象,而对象本质上是一个对象,但不一定是一个函数。

图例:
在这里插入图片描述

结论:普通对象是一个对象,他通过 new 一个函数 来创建。函数也是一个对象,它通过 new Function 来创建。

看到图例这里,或许有的小伙伴又产生疑问:大写的 Function 其实本质上也是一个函数及构造函数,同时上面说过函数也是一个对象,而对象也一定是通过,new 一个函数创建的 ,那么好奇 Function 又是怎么来的呢?他又是 new 谁创建的呢?其实在这里,需要说明一下的就是 Function 是一个比较特殊的存在,它是 JS 引擎 启动的时候,被直接放在 内存中的,它不通过任何东西来创建。

补充
只有普通函数 才能够被 new,用来作为一个构造函数使用。
由于函数也是一个对象,所以函数身上可以有属性或方法
所有对象都是引用类型,赋值的时候实际上是赋值的一个地址,用来指向一块内存空间


原型 prototype

所有函数身上都有一个属性:prototype,被称之为 函数原型

在这里插入图片描述

默认情况下,prototype 是一个普通的 Object 对象,并且在 prototype 中默认会携带一个属性 叫做 constructor 的属性,它也是一个对象(函数对象),它指向当前构造函数自身。

在这里插入图片描述
在这里插入图片描述

理解图例:
在这里插入图片描述


隐式原型 __ proto __

所有对象都有一个属性 __proto__,他被称之为隐式原型

在这里插入图片描述

默认情况下 隐式原型指向创建该对象构造函数原型

在这里插入图片描述
图例:
在这里插入图片描述

当访问一个对象的属性成员时。

  1. 首先会在当前对象自身上查找,如果属性存在,则直接使用。
  2. 如果不存在,则会在当前对象的 隐式原型 上查看自己的构造函数身上有没有该属性,如果找到了就使用,没找到就继续向顶层查找,直到找到顶层的 Object 的身上,如果还没找到,这时候就会报错抛出异常。

原型链

所谓的原型链 其实就是 一个对象 由下逐步向上层逐层查找属性成员的一种形式描述

在这里插入图片描述

__proto__ 在进行向上查找时,由于 __proto__ 自身也是对象,所以也可以调用 自身的 __proto__,这样的过程,由于看起来,像是一个链条一样,故而被称之为 原型链

图例分析:
在这里插入图片描述
补充:

  • Function 隐式原型指向自身的原型(特殊点)
  • Obiect.prototype.__proto__ 指向 null (查找到顶层了,实在是没有了)

在这里插入图片描述


在这里插入图片描述


🚵‍♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼‍♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————