Skip to content
New issue

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

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

Already on GitHub? Sign in 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 则是原型对象真正创建和存储的地方,在这里可以定义一些公用的属性和方法。

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

No branches or pull requests

1 participant