JavaScript 中對象的自有和繼承屬性
在 JavaScript 中,對像只是稱為屬性的鍵值對的集合。每個屬性都有一個鍵和一個值。屬性鍵可以是字符串或符號,值可以是任何東西。
與 Java、C# 或 Python 等其他編程語言不同,JavaScript 中沒有真正的類的概念。 JavaScript 中幾乎所有的對像都是 Object
的實例;從 Object.prototype
繼承屬性的全局對象 .由於這種原型繼承,對象的屬性可以是自己的 或繼承 .
在本文中,您將了解 JavaScript 中對象自身屬性和繼承屬性之間的區別。
自有屬性
直接在對像上定義的屬性 被稱為自己的財產。
讓我們創建一個新的 JavaScript 對象:
const user = {
name: 'John Doe',
age: 25
};
以上user
object 是一個普通的 JavaScript 對象,它定義了兩個自己的屬性 name
和 age
,直接上就可以了。
要列出對象的所有自身屬性,可以使用名為 Object.getOwnPropertyNames()
的內置方法 :
const user = {
name: 'John Doe',
age: 25
};
const props = Object.getOwnPropertyNames(user);
console.log(props); // [ 'name', 'age' ]
要檢查一個屬性是對象自己的還是繼承的屬性,可以調用 hasOwnProperty()
對像上的方法:
user.hasOwnProperty('name'); // true
user.hasOwnProperty('email'); // false
繼承的屬性
繼承屬性是對象從原型繼承的屬性 對象。
例如,每個 JavaScript 對像都繼承 toString
來自其原型對象的屬性,該對象評估為一個函數:
user.toString; // function() {...}
當 JavaScript 計算上述表達式時 (user.toString
),它首先查看 user
的自身屬性 找到 toString
財產。由於它是繼承屬性,因此搜索將失敗。然後 JavaScript 移動到 user
的原型對象 並找到 toString
屬性。
嵌套對象繼承
原型對像不是唯一的 繼承屬性的方式。您甚至可以使用現有對像作為原型創建新對象並繼承其所有屬性。
下面的示例創建一個名為 employee
的對象 繼承自 user
對象:
const user = {
name: 'John Doe',
age: 25
};
const employee = Object.create(user, {
department: {
value: 'HR',
enumerable: true
}
});
employee.hasOwnProperty('name'); // false
employee.hasOwnProperty('department'); // true
employee
對像有自己的屬性 department
, 並繼承 name
和 age
其原型 user
的屬性 .
覆蓋繼承的屬性
您還可以覆蓋繼承的屬性並直接在對像上定義它們。
讓我們定義 toString
屬性直接在 user
對象:
const user = {
name: 'John Doe',
age: 25,
toString() {
return 'Hey there!';
}
};
user.toString(); // Hey there!
自 user
對象定義了自己的toString
屬性現在,它不再從原型對象繼承它:
// get object prototype
const proto = Object.getPrototypeOf(user);
user.toString === proto.toString; // false
Object.getPrototypeOf()
方法用於在 JavaScript 中獲取原型對象。
當一個對象定義了自己的屬性並繼承了同名的屬性時,自己的屬性優先 超過繼承的。
但是,如果您出於某種原因刪除了自己的屬性,那麼繼承的屬性將再次可用:
user.toString(); // Hey there!
// delete own property
delete user.toString;
// inherited property
user.toString(); // [object Object]
總結
JavaScript 對象可以擁有自己的屬性和繼承的屬性。屬性可以是自有的,也可以是繼承的。
自己的屬性直接在對像上定義。另一方面,繼承的屬性是從原型對象繼承而來的。
您還可以通過 Object.create()
繼承現有對象的屬性 方法。
覆蓋原型屬性沒有限制,但不建議這樣做。