【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__
,他被称之为隐式原型
。
默认情况下 隐式原型
指向创建该对象
的构造函数
的原型
图例:
当访问一个对象的属性成员时。
- 首先会在当前对象自身上查找,如果属性存在,则直接使用。
- 如果不存在,则会在当前对象的
隐式原型
上查看自己的构造函数身上有没有该属性,如果找到了就使用,没找到就继续向顶层查找,直到找到顶层的Object
的身上,如果还没找到,这时候就会报错抛出异常。
原型链
所谓的原型链 其实就是 一个
对象 由下逐步向上层逐层查找属性成员的一种形式描述
。
__proto__
在进行向上查找时,由于 __proto__
自身也是对象,所以也可以调用 自身的 __proto__
,这样的过程,由于看起来,像是一个链条一样,故而被称之为 原型链
图例分析:
补充:
Function
的隐式原型
指向自身的原型
(特殊点)Obiect.prototype.__proto__
指向null
(查找到顶层了,实在是没有了)
🚵♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————