Object.prototype.__proto__

这篇翻译不完整。请帮忙从英语翻译这篇文章

警告: 通过现代浏览器的操作属性的便利性,可以改变一个对象的 [[Prototype]] 属性, 这种行为在每一个JavaScript引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,并且性能消耗的时间也不是简单的花费在 obj.__proto__ = ... 语句上, 它还会影响到所有继承来自该 [[Prototype]] 的对象,如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]].。相反, 创建一个新的且可以继承 [[Prototype]] 的对象,推荐使用 Object.create()

警告: 当对象的原型 __proto__ 属性已被大多数浏览器厂商所支持的今天,它的存在和使用行为,只是为了ECMAScript 6标准规范作为遗产特征而确保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()的替代。 See: object initializer / literal syntax.

语法

var shape = {};
var circle = new Circle();
 
// 设置该对象的原型链引用
// 过时且不推荐使用的。这里只是举个栗子, 尽量不要在生产环境中这样做。
shape.__proto__ = circle;

// 判断该对象的原型链引用是否属于circle
console.log(shape.__proto__ === circle); // true
var shape = function () {
};
var p = {
    a: function () {
        console.log('aaa');
    }
};
shape.prototype.__proto__ = p;

var circle = new shape();

circle.a();//aaa

console.log(shape.prototype === circle.__proto__);//true

//或者

var shape = function () {
};
var p = {
    a: function () {
        console.log('a');
    }
};

var 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');

}
var a = new test()

console.log(a.__proto__ === test.prototype);//true

a.myname();//myname


//或者

var fn = function () {
};
fn.prototype.myname = function () {
    console.log('myname');
}

var obj = {
    __proto__: fn.prototype
};


obj.myname();//myname

注意:这是两个下划线,后面是五个字符的 “proto” ,后面再跟两个下划线。

描述

The __proto__ getter function exposes the value of the internal [[Prototype]] of an object. For objects created using an object literal, this value is Object.prototype. For objects created using array literals, this value is Array.prototype. For functions, this value is Function.prototype. For objects created using new fun, where fun is one of the built-in constructor functions provided by JavaScript (Array, Boolean, Date, Number, Object, String, and so on — including new constructors added as JavaScript evolves), this value is always fun.prototype. For objects created using new fun, where fun is a function defined in a script, this value is the value of fun.prototype. (That is, if the constructor didn't return an other object explicitly, or the fun.prototype has been reassigned since the instance was created).

The __proto__ setter allows the [[Prototype]] of an object to be mutated. The object must be extensible according to Object.isExtensible(): if it is not, a TypeError is thrown. The value provided must be an object or null. Providing any other value will do nothing.

To understand how prototypes are used for inheritance, see guide article Inheritance and the prototype chain.

The __proto__ property is a simple accessor property on Object.prototype consisting of a getter and setter function. A property access for __proto__ that eventually consults Object.prototype will find this property, but an access that does not consult Object.prototype will not find it. If some other __proto__ property is found before Object.prototype is consulted, that property will hide the one found on 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 2017 Draft (ECMA-262)
Object.prototype.__proto__
Draft  

浏览器兼容情况

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) 11 (Yes) (Yes)
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)

兼容性注意事项

在 ECMAScript 2015(ES6)的规范要求中,支持__proto__ 是各大Web浏览器厂商的要求(虽然符合规范),但其他环境下因为历史遗留的问题,也有可能被使用和支持。 

更多请参考

文档标签和贡献者

 此页面的贡献者: Wayme, lisniuse, redcool007, Leslie2014, teoli, ziyunfei
 最后编辑者: Wayme,