Object.prototype.__proto__ - JavaScript 编辑
已废弃
该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。
警告: 通过现代浏览器的操作属性的便利性,可以改变一个对象的 [[Prototype]]
属性, 这种行为在每一个JavaScript引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,并且性能消耗的时间也不是简单的花费在 obj.__proto__ = ...
语句上, 它还会影响到所有继承来自该 [[Prototype]]
的对象,如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]]。相反, 创建一个新的且可以继承 [[Prototype]]
的对象,推荐使用 Object.create()
。
警告: 当Object.prototype.__proto__
已被大多数浏览器厂商所支持的今天,其存在和确切行为仅在ECMAScript 2015规范中被标准化为传统功能,以确保Web浏览器的兼容性。为了更好的支持,建议只使用 Object.getPrototypeOf()
。
Object.prototype
的 __proto__
属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]]
(一个对象或 null
)。使用__proto__
是有争议的,也不鼓励使用它。因为它从来没有被包括在EcmaScript语言规范中,但是现代浏览器都实现了它。__proto__
属性已在ECMAScript 6语言规范中标准化,用于确保Web浏览器的兼容性,因此它未来将被支持。它已被不推荐使用, 现在更推荐使用Object.getPrototypeOf
/Reflect.getPrototypeOf
和Object.setPrototypeOf
/Reflect.setPrototypeOf
(尽管如此,设置对象的[[Prototype]]是一个缓慢的操作,如果性能是一个问题,应该避免)。
__proto__ 属性也可以在对象文字定义中使用对象[[Prototype]]来创建,作为Object.create()
的一个替代。 请参阅: object initializer / literal syntax.
语法
let Circle = function () {};
let shape = {};
let circle = new Circle();
// 设置该对象的原型链引用
// 过时且不推荐使用的。这里只是举个例子,尽量不要在生产环境中这样做。
shape.__proto__ = circle;
// 判断该对象的原型链引用是否属于circle
console.log(shape.__proto__ === circle); // true
let shape = function () {};
let p = {
a: function () {
console.log('aaa');
}
};
shape.prototype.__proto__ = p;
let circle = new shape();
circle.a();//aaa
console.log(shape.prototype === circle.__proto__);//true
//或者
let shape = function () {};
var p = {
a: function () {
console.log('a');
}
};
let circle = new shape();
circle.__proto__ = p;
circle.a(); // a
console.log(shape.prototype === circle.__proto__);//false
//或者
function test() {}
test.prototype.myname = function () {
console.log('myname');
}
let a = new test()
console.log(a.__proto__ === test.prototype);//true
a.myname();//myname
//或者
let fn = function () {};
fn.prototype.myname = function () {
console.log('myname');
}
let obj = {
__proto__: fn.prototype
};
obj.myname();//myname
注意:这是两个下划线,后面是五个字符的 “proto” ,后面再跟两个下划线。
描述
__proto__的读取器(getter)暴露了一个对象的内部 [[Prototype]]
。对于使用对象字面量创建的对象,这个值是 Object.prototype
。对于使用数组字面量创建的对象,这个值是 Array.prototype
。对于functions,这个值是Function.prototype
。对于使用 new fun 创建的对象,其中fun是由js提供的内建构造器函数之一(Array
, Boolean
, Date
, Number
, Object
, String
等等),这个值总是fun.prototype。对于用js定义的其他js构造器函数创建的对象,这个值就是该构造器函数的prototype属性。
__proto__ 的设置器(setter)允许对象的 [[Prototype]]被变更。前提是这个对象必须通过
Object.isExtensible()
判断为是可扩展的,如果不可扩展,则会抛出一个 TypeError
错误。要变更的值必须是一个object或null
,提供其它值将不起任何作用。
要理解原型如何被使用,请查看相关文章:Inheritance and the prototype chain。
.__proto__属性是Object.prototype
一个简单的访问器属性,其中包含了get(获取)和set(设置)的方法,任何一个__proto__的存取属性都继承于Object.prototype
,但一个访问属性如果不是来源于Object.prototype
就不拥有.__proto__属性,譬如一个元素设置了其他的.__proto__属性在Object.prototype
之前,将会覆盖原有的Object.prototype
。
规范
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Object.prototype.__proto__ | Standard | Included in the (normative) annex for additional ECMAScript legacy features for Web browsers (note that the specification codifies what is already in implementations). |
ECMAScript (ECMA-262) Object.prototype.__proto__ | Living Standard |
浏览器兼容情况
BCD tables only load in the browser
The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.兼容性注意事项
在 ECMAScript 2015(ES6)的规范要求中,支持__proto__
是各大Web浏览器厂商的要求(虽然符合规范),但其他环境下因为历史遗留的问题,也有可能被使用和支持。
更多请参考
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论