Giống như các loại dữ liệu khác,
đối tượng kế thừa các thuộc tính và phương thức của nguyên mẫu Object
tích hợp sẵn,
nghĩa là đối tượng thu được sẽ chứa cả thuộc tính mà bạn đã xác định và
thuộc tính nguyên mẫu chứa các phương thức kế thừa từ nguyên mẫu:
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__()
Bạn không nên truy cập trực tiếp các thuộc tính nguyên mẫu bằng khoá thuộc tính. Như
mà bạn có thể nhận thấy trong ví dụ trước, điều này được ngụ ý trong [[prototype]]
hoặc ký hiệu <prototype>
dùng trong trình duyệt bảng điều khiển dành cho nhà phát triển và các nguồn
tài liệu về khoá thuộc tính của nguyên mẫu:
// Chrome:
let emptyObject = {};
emptyObject;
> {}
[[prototype]]: Object
// Firefox:
let emptyObject = {};
emptyObject;
> Object { }
<prototype>: Object { … }
Mặc dù tất cả trình duyệt phổ biến đều sử dụng __proto__
làm tiêu chuẩn trên thực tế, nhưng đây không phải là
được chuẩn hoá chính thức và nên tránh sử dụng trong mã phát hành chính thức.
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__()
Thay vào đó, bạn có thể trực tiếp truy cập và sửa đổi [[Prototype]]
của một đối tượng
bằng Object.getPrototypeOf()
và Object.setPrototypeOf()
tích hợp sẵn
phương thức:
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 }
Để phân biệt giữa thuộc tính kế thừa và thuộc tính do tác giả xác định, phương thức phần sau thường được gọi là "thuộc tính riêng" của đối tượng.
Phương thức Object.hasOwn()
tích hợp sẵn sẽ trả về true
nếu thuộc tính được chỉ định
là một thuộc tính trực tiếp của đối tượng và false
nếu thuộc tính đó được kế thừa hoặc
không tồn tại. Bất cứ khi nào có thể, hãy sử dụng Object.hasOwn()
thay cho phương thức hasOwnProperty()
kế thừa (phương thức này không hỗ trợ
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
Kiểm tra kiến thức
Tại sao bạn nên tránh sử dụng __proto__
?