嗯...首先对于这个标题表示抱歉 :)
感觉有点标题党了,但是最初写这篇文章的目的也是为了让不懂的初学者能一下子看懂这三个东西的区别,而不是在长篇大论中退缩
这篇文章中的内容来自我的个人理解和 MDN 文档,如果有任何错误欢迎指出
对于初学者来说, Prototype 似乎还好理解一些,但是在进行更深入的学习研究之后或许会有点晕,一些文章中 obj.prototype
和 obj.[[prototype]]
中的两种写法区别在哪?分别指的是什么?还有 __proto__
呢?
obj.prototype 中的 prototype: 是指类型 (Type) 上的原型对象 (Prototype object)
obj.[[prototype]] 中的 [[prototype]]: 是指实例 (Instance) 中指向创建这个实例的类型上的原型对象的 "链接"
obj.__proto__
: 这个属性实际和上面的 [[prototype]] 是同样的东西,在过去被各大浏览器作为非标准属性实现
其实你应该已经猜到了,[[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__ = xxx
或 Object.setPrototypeOf()
来修改对象的 [[prototype]],这在所有 JavaScript ,因为这会导致一些内部优化失效,造成的性能影响不仅是对于修改 [[prototype]] 的过程,甚至包括任何对于这个修改过的对象的访问。
解决方案是使用 Object.Create()
来创建一个新的对象并设置将要设置为原型对象的对象传入参数中。
这篇文章来自我的博客 > https://aka.mn/2016/10/31/difference-in-prototype-and-proto/
为了避免赚点击量的嫌疑,作为全文发布,文章中如果有任何错误欢迎指出