js原型链理解
原型链
- 原型 (prototype)
- 每个函数上面都有一个prototype属性(天生的),因为这个属性的值是个对象,也被称之为原型对象
- 函数和构造函数的区别:构造函数和普通函数在js中都是一样的没有区别,只是大家约定俗成构造函数首字母必须大写,用来区分于普通函数(驼峰命名)
- 作用
- 存放一些属性和方法
- 在JavaScript中实现继承
- 案例:实例化函数继承方法
const arr = new Array(1,2,3);
arr.reverse(); // 反转
arr.sort(); // 排序
console.log(typeof Array); // function (万物皆起源于函数=.=)
- 为什么 Array函数在实例化之后就可以使用一些 reverse sort方法啊
-
官方在Array函数(构造函数)的prototype原型上,已经挂载了很多方法
-
Array函数的prototype方法如下
-
我们通过new Array()的到一个实例,而这个实例是一个Object 对象, 这就得涉及到了对象上得__proto__属性了
- 原型链(链接点): proto
- 每个Object对象都会有__proto__属性(天生的)
- 作用: 这个属性指向它的构造函数的原型。
- 问题:它的构造函数是谁?构造函数的原型又是谁
- 我们上面写了,Array是一个构造函数,new Array()是实例化了这个构造函数,而这个实例的构造函数也就是指向的 Arrar函数,new Array的构造函数的原型,就是Array的原型(prototype)
- 现在我们知道__proto__指向它的构造函数的原型(Array.prototype),我们调用reverse() stor()方法的时候他是如何查找的呢
-
这个就涉及到js的原型链查找了,当你去调用 arr.stor() 方法的时候,我们知道arr是个对象{},我们就去对象的prop属性上去查找是否有该属性
-
如果没有该属性,就回去该对象的__proto__上查找(官方定义的查找规则),arr.proto 指向的就是它的构造函数的原型(prototype) -> Array.prototype
-
找到 Array.prototype 之后发现上面有官方定义的一些方法,就可以调用了
-
假如这个构造函数的原型上,没有sort()这个方法, 会怎么查找呢?
-
我们知道 构造函数的原型(Array.prototype)是个对象,我们上面又提到 每个Object对象都会有__proto__属性(天生的),这时候它就会到构造函数的原型对象上的 proto 上查找,我们又知道 proto 属性指向它的构造函数的原型,这里问题来了 Array.prototype “对象” 的构造函数是谁啊?
-
Array.prototype.proto == Object.prototype, 是的 Array.prototype.proto 的构造函数就是Object “函数”,注意Object是函数
-
Object 是函数它就有 prototype 属性,函数的prototype 是对象类型,对象天生又有 proto 属性,那么 Object.prototype.proto 是什么呢,答案是null,到这里我们就找到了根了(Object.prototype.proto),这个查找的过程其实就是原型链,而 proto 属性是原型链中链接的一个点,更加准确一点来说, proto 是 “链接点”
原型链图片: