Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

JS 基础篇 - prototype与__proto__的关系与区别 #51

Open
jtwang7 opened this issue Nov 2, 2021 · 0 comments
Open

JS 基础篇 - prototype与__proto__的关系与区别 #51

jtwang7 opened this issue Nov 2, 2021 · 0 comments

Comments

@jtwang7
Copy link
Owner

jtwang7 commented Nov 2, 2021

参考文章:

前言 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 的联系

  1. __proto__ 存在于所有对象上, prototype 只存在于函数上;
  2. 每个对象都对应一个原型对象, 并从原型对象继承属性和方法, 该对应关系由 __proto__ 实现(访问对象内部属性[[Prototype]]);
  3. prototype 用于存储共享的属性和方法, 其作用主要体现在 new 创建对象时, 为 __proto__ 构建一个对应的原型对象(设置实例对象的内部属性[[Prototype]]);
  4. __proto__ 不是 ECMAScript 语法规范的标准, 是浏览器厂商实现的一种访问和修改对象内部属性 [[Prototype]] 的访问器属性(getter/setter), 现常用 ECMAScript 定义的 Object.getPrototypeOfObject.setPrototypeOf 代替;
  5. prototype 是 ECMAScript 语法规范的标准;

总结来说:[[Prototype]] 是对象内维护其对应原型对象的属性,但它不可直接被外界访问和修改;__proto__ 是浏览器厂商实现的访问和修改对象内部属性 [[Prototype]] 的访问器属性(getter/setter),不规范,现多用ECMAScript 定义的 Object.getPrototypeOfObject.setPrototypeOf 代替;而 prototype 则是原型对象真正创建和存储的地方,在这里可以定义一些公用的属性和方法。

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant