原型继承

其他数据类型一样, 对象从内置的 Object 原型继承属性和方法, 这意味着生成的对象同时包含您定义的属性和 proto 属性,其中包含从原型继承的方法:

let myObject = {
   
'booleanValue' : true
};

myObject
;
> Object { booleanValue: true }
    booleanValue
: true
   
[[prototype]]: Object { }
            __defineGetter__
: function __defineGetter__()
            __defineSetter__
: function __defineSetter__()
            __lookupGetter__
: function __lookupGetter__()
            __lookupSetter__
: function __lookupSetter__()
            __proto__
:
                constructor
: function Object()
                hasOwnProperty
: function hasOwnProperty()
                isPrototypeOf
: function isPrototypeOf()
                propertyIsEnumerable
: function propertyIsEnumerable()
                toLocaleString
: function toLocaleString()
                toString
: function toString()
                valueOf
: function valueOf()
               
<get __proto__()>: function __proto__()
               
<set __proto__()>: function __proto__()

原型属性不应直接通过属性键进行访问。如 在上一个示例中,[[prototype]] 暗示了这一点 或以 <prototype> 表示法表示和来源 关于原型的属性键的文档:

// Chrome:
let emptyObject
= {};

emptyObject
;
> {}
 
[[prototype]]: Object
// Firefox:
let emptyObject
= {};

emptyObject
;
> Object {  }
 
<prototype>: Object { }

虽然所有常用浏览器都使用 __proto__ 作为事实上的标准,但这并不是 已正式标准化,应避免使用正式版代码。

let emptyObject = {};

emptyObject
.__proto__;
> Object { }
    __defineGetter__
: function __defineGetter__()
    __defineSetter__
: function __defineSetter__()
    __lookupGetter__
: function __lookupGetter__()
    __lookupSetter__
: function __lookupSetter__()
    __proto__
:
        constructor
: function Object()
        hasOwnProperty
: function hasOwnProperty()
        isPrototypeOf
: function isPrototypeOf()
        propertyIsEnumerable
: function propertyIsEnumerable()
        toLocaleString
: function toLocaleString()
        toString
: function toString()
        valueOf
: function valueOf()
       
<get __proto__()>: function __proto__()
       
<set __proto__()>: function __proto__()

相反,您可以直接访问和修改对象的 [[Prototype]], 使用内置的 Object.getPrototypeOf()Object.setPrototypeOf() 方法:

let myObj = { "value" : 5 };
let protoParent
= { "protoValue" : true };

myObj
;
Object { value: 5 }
    value
: 5
   
<prototype>: Object { }

Object.getPrototypeOf( myObj );
> Object { }
    __defineGetter__
: function __defineGetter__()
    __defineSetter__
: function __defineSetter__()
    __lookupGetter__
: function __lookupGetter__()
    __lookupSetter__
: function __lookupSetter__()
    __proto__
:
    constructor
: function Object()
    hasOwnProperty
: function hasOwnProperty()
    isPrototypeOf
: function isPrototypeOf()
    propertyIsEnumerable
: function propertyIsEnumerable()
    toLocaleString
: function toLocaleString()
    toString
: function toString()
    valueOf
: function valueOf()
   
<get __proto__()>: function __proto__()
   
<set __proto__()>: function __proto__()

Object.setPrototypeOf( myObj, protoParent );
> Object { value: 5 }
    value
: 5
   
<prototype>: Object { protoValue: true }

为了区分继承的属性和作者定义的属性, 后者通常称为对象“自己的属性”。

如果指定属性,则内置 Object.hasOwn() 方法会返回 true 是对象的直接属性,如果该属性false是继承的或 不存在。请尽可能使用 Object.hasOwn() 而不是继承的 hasOwnProperty() 方法,该方法不支持 Object.create()

let myObject = {
   
'myValue' : 100
};

Object.hasOwn( myObject, 'myValue' );
> true

myObject
.__proto__; // The Object prototype inherited by `myObject` is present:
> Object { }

Object.hasOwn( myObject, '__proto__' ); // The Object prototype inherited by `myObject` is not an "own property:"
> false

检查您的理解情况

为什么应避免使用 __proto__

它不是标准化的。
这会让日后的代码维护者感到困惑。
很多浏览器都不支持此功能。