一句话看懂 Prototype, [[Prototype]], __proto__的区别

2016-10-31 18:10:15 +08:00
 invalidtoken

嗯...首先对于这个标题表示抱歉 :)

感觉有点标题党了,但是最初写这篇文章的目的也是为了让不懂的初学者能一下子看懂这三个东西的区别,而不是在长篇大论中退缩

这篇文章中的内容来自我的个人理解和 MDN 文档,如果有任何错误欢迎指出


对于初学者来说, Prototype 似乎还好理解一些,但是在进行更深入的学习研究之后或许会有点晕,一些文章中 obj.prototypeobj.[[prototype]] 中的两种写法区别在哪?分别指的是什么?还有 __proto__ 呢?

一句话解释:

obj.prototype 中的 prototype: 是指类型 (Type) 上的原型对象 (Prototype object)

obj.[[prototype]] 中的 [[prototype]]: 是指实例 (Instance) 中指向创建这个实例的类型上的原型对象的 "链接"

obj.__proto__: 这个属性实际和上面的 [[prototype]] 是同样的东西,在过去被各大浏览器作为非标准属性实现

In Depth :

其实你应该已经猜到了,[[prototype]] 并不是一个真正存在于 obj 或是它的原型链上的一个属性,它存在于 JavaScript 引擎的内部,这样写是为了区分类型上的 prototype 属性和这个实例上的"链接"属性。

在实例上获取原型对象的正确的方式是使用 Object.getProtoTypeOf() 这个在 ECMAScript 5.1 及以后版本的实现中可用,根据 MDN 提供的资料,兼容的浏览器版本为 Chrome 5+, Firefox 3.5+ , Internet Explorer 9+, Safari 5+

__proto__ 是一个非标准的属性,由于广泛的支持和使用在 ECMAScript 2015 中被纳入标准,但是这只是作为兼容性考虑,建议使用 Object.getPrototypeOf() 代替

一般像 __proto__ 这样以两个下划线开始的写法为私有属性或私有方法,类似于 CSS 中横线开头为私有前缀

提示:

如果你对性能比较敏感, MDN 文档建议不要更改对象的 [[prototype]] 属性,即使用 obj.__proto__ = xxxObject.setPrototypeOf() 来修改对象的 [[prototype]],这在所有 JavaScript ,因为这会导致一些内部优化失效,造成的性能影响不仅是对于修改 [[prototype]] 的过程,甚至包括任何对于这个修改过的对象的访问。

解决方案是使用 Object.Create() 来创建一个新的对象并设置将要设置为原型对象的对象传入参数中。

其他

这篇文章来自我的博客 > https://aka.mn/2016/10/31/difference-in-prototype-and-proto/

为了避免赚点击量的嫌疑,作为全文发布,文章中如果有任何错误欢迎指出

1498 次点击
所在节点    JavaScript
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/316856

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX