【JavaScript】JavaScript原型链
# 【JavaScript】JavaScript 原型链
# 2023/4/17 重温一下多年前的八股文
# 对象
要清楚原型链,首先要弄清楚对象:
-
普通对象
-
- 最普通的对象:有__proto__属性(指向其原型链),没有 prototype 属性。
- 原型对象 (Person.prototype 原型对象还有 constructor 属性(指向构造函数对象))
-
函数对象:
- 凡是通过 new Function () 创建的都是函数对象。
拥有__proto__、prototype 属性(指向原型对象)。
Function、Object、Array、Date、String、自定义函数
特例: Function.prototype (是原型对象,却是函数对象,下面会有解释)
1 | //函数对象 |
Array 是函数对象,是 Function 的实例对象,Array 是通过 newFunction 创建出来的。因为 Array 是 Function 的实例,所以 Array.proto === Function.prototype
1 | //普通对象 |
# 原型对象
每创建一个函数都会有一个 prototype 属性,这个属性是一个指针,指向一个对象(通过该构造函数创建实例对象的原型对象)。原型对象是包含特定类型的所有实例共享的属性和方法。原型对象的好处是,可以让所有实例对象共享它所包含的属性和方法。
第一块中有提到,原型对象属于普通对象。Function.prototype 是个例外,它是原型对象,却又是函数对象,作为一个函数对象,它又没有 prototype 属性。
1 | function Person(){}; |
解释:
其实原型对象就是构造函数的一个实例对象。person.prototype 就是 person 的一个实例对象。相当于在 person 创建的时候,自动创建了一个它的实例,并且把这个实例赋值给了 prototype。
1 | function Person(){}; |
从一张图看懂原型对象、构造函数、实例对象之间的关系
1 | function Dog(){}; |
1 | //图中的一些关系 |
# 原型链
原型链是实现继承的主要方法。
先说一下继承,许多 OO 语言都支持两张继承方式:接口继承、实现继承。
|- 接口继承:只继承方法签名
|- 实现继承:继承实际的方法
由于函数没有签名,在 ECMAScript 中无法实现接口继承,只支持实现继承,而实现继承主要是依靠原型链来实现。
原型链基本思路:
利用原型让一个引用类型继承另一个引用类型的属性和方法。
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数想指针 (constructor),而实例对象都包含一个指向原型对象的内部指针 (proto)。如果让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针 (proto),另一个原型也包含着一个指向另一个构造函数的指针 (constructor)。假如另一个原型又是另一个类型的实例…… 这就构成了实例与原型的链条。
原型链基本思路(图解):
举例说明:
1 | function Animal(){ |
图解:
详细图
(图片修正:笔误,第一行应该是 xiaohuang.proto === Dog.prototype)
从 xiaohuang 这个实例,看出整个链条
总结:
Xiaohuang 这个 Dog 的实例对象继承了 Animal,Animal 继承了 Object。
# 关于我
Brath 是一个热爱技术的 Java 程序猿,公众号「InterviewCoder」定期分享有趣有料的精品原创文章!
非常感谢各位人才能看到这里,原创不易,文章如果有帮助可以关注、点赞、分享或评论,这都是对我的莫大支持!