-
Notifications
You must be signed in to change notification settings - Fork 3
Description
参考文章:
- 详解原型链中的prototype和 proto
- proto 和 prototype 到底有什么区别
- 从__proto__和prototype来深入理解JS对象和原型链
- 隔壁小孩也能看懂的 7 种 JavaScript 继承实现
前言 Object & Function
JS 中引用类型有很多: Object, Function, Array, Date …;
其中 Object, Function 是能被 typeof 识别的, 其余的本质上都是 Object 的衍生对象;
Function 在 JS 中被单独视为一类, 是因为它在 JS 中是所谓的一等公民, JS 中没有类的概念, 其是通过函数来模拟类的;
尽管 Function 被单独视为一类,但从形式上看,它还是一个 Object 对象,那么我们如何区分 Function 和 Object 呢?答案就是 prototype
prototype & [[Prototype]]
prototype 是用来区分 Function 和 Object 的关键:
函数创建时, JS 会为函数自动添加 prototype 属性, 其值为一个带有 constructor 属性(指向对应的构造函数)的对象,这个对象就是我们所说的原型对象,除了 constructor 属性外,我们还可以在上面添加一些公用的属性和方法;
Function.prototype = {
constructor: Function,
// ...
}
而每个对象则都有一个内部属性[[Prototype]]
, 其用于存放该对象对应的原型对象。
但是对象的内部属性[[Prototype]]
是无法被直接访问和获取的,需要通过 __proto__
, Object.getPrototypeOf
/ Object.setPrototypeOf
访问.
你可以理解为,
[[Prototype]]
存放了对原型对象的引用,真正的原型对象是由Function.prototype
创建和维护的。
prototype 与 proto 的联系
__proto__
存在于所有对象上,prototype
只存在于函数上;- 每个对象都对应一个原型对象, 并从原型对象继承属性和方法, 该对应关系由
__proto__
实现(访问对象内部属性[[Prototype]]
); prototype
用于存储共享的属性和方法, 其作用主要体现在 new 创建对象时, 为__proto__
构建一个对应的原型对象(设置实例对象的内部属性[[Prototype]]
);__proto__
不是 ECMAScript 语法规范的标准, 是浏览器厂商实现的一种访问和修改对象内部属性[[Prototype]]
的访问器属性(getter/setter), 现常用 ECMAScript 定义的Object.getPrototypeOf
和Object.setPrototypeOf
代替;prototype
是 ECMAScript 语法规范的标准;
总结来说:
[[Prototype]]
是对象内维护其对应原型对象的属性,但它不可直接被外界访问和修改;__proto__
是浏览器厂商实现的访问和修改对象内部属性[[Prototype]]
的访问器属性(getter/setter),不规范,现多用ECMAScript 定义的Object.getPrototypeOf
和Object.setPrototypeOf
代替;而prototype
则是原型对象真正创建和存储的地方,在这里可以定义一些公用的属性和方法。