JS操作物件屬性(獲取、新增、刪除、修改物件屬性)

2020-07-16 10:05:07
屬性也稱為名值對,包括屬性名和屬性值。屬性名可以是包含空字串在內的任意字串,一個物件中不能存在兩個同名的屬性。屬性值可以是任意型別的資料。

定義屬性

1. 直接量定義

在物件直接量中,屬性名與屬性值之間通過冒號分隔,冒號左側是屬性名,右側是屬性值,名值對(屬性)之間通過逗號分隔。

範例1

在下面範例中,使用直接量方法定義物件 obj,然後新增了兩個成員,一個是屬性,另一個是方法。
var obj = {
    x : 1,
    y : function () {
        return this.x + this.x;
    }
}

2. 點語法定義

範例2

通過點語法,可以在建構函式內或者物件外新增屬性。
var obj = {};
obj.x = 1;
obj.y = function () {
    return this.x + this.x;
}

3. 使用 Object.defineProperty

使用 Object.defineProperty() 函數可以為物件新增屬性,或者修改現有屬性。如果指定的屬性名在物件中不存在,則執行新增操作;如果在物件中存在同名屬性,則執行修改操作。

具體用法如下:

Object.defineProperty(object, propertyname, descriptor);

引數說明如下:
  • object:指定要新增或修改屬性的物件,可以是 JavaScript 物件或者 DOM 物件。
  • propertyname:表示屬性名的字串。
  • descriptor:定義屬性的描述符,包括對資料屬性或存取器屬性。

Object.defineProperty 返回值為已修改的物件。

範例3

下面範例先定義一個物件直接量 obj,然後使用 Object.defineProperty() 函數為 obj 物件定義屬性,屬性名為 x,值為 1,可寫、可列舉、可修改特性。
var obj = {};
Object.defineProperty(obj, "x", {
    value : 1,
    writable : true,
    enumerable : true,
    configurable : true
});
console.log(obj.x);  //1

4. 使用 Object.defineProperties

使用 Object.defineProperties() 函數可以一次定義多個屬性。具體用法如下:

object.defineProperties(object, descriptors);

引數說明如下:
  • object:對其新增或修改屬性的物件,可以是本地物件或 DOM 物件。
  • descriptors:包含一個或多個描述符物件,每個描述符物件描述一個資料屬性或存取器屬性。

範例4

在下面範例中,使用 Object.defineProperties() 函數將資料屬性和存取器屬性新增到物件 obj 上。
var obj = {};
Object.defineProperties(obj, {
    x : {  //定義屬性x
        value : 1,
        writable : true,  //可寫
    },
    y : {  //定義屬性y
        set : function (x) {  //設定存取器屬性
            this.x = x;  //改寫obj物件的x屬性的值
        },
        get : function () {  //設定存取器
            return this.x;
        },
    }
});
obj.y = 10;
console.log(obj.x);  //10

讀寫屬性

1. 使用點語法

使用點語法可以快速讀寫物件屬性,點語法左側是參照物件的變數,右側是屬性名。

範例1

下面範例定義物件 obj,包含屬性 x,然後使用點語法讀取屬性 x 的值。
var obj = {  //定義物件
    x : 1
}
console.log(obj.x);  //存取物件屬性x,返回1
obj.x = 2;  //重寫屬性值
console.log(obj.x);  //存取物件屬性x,返回2

2. 使用中括號語法

從結構上分析,物件與陣列相似,因此可以使用中括號來讀寫物件屬性。

範例2

針對上面範例,可以使用中括號來讀寫物件屬性。
console.log(obj["x"]);  //2
obj["x"] = 3;  //重寫屬性值
console.log(obj["x"]);  //3

【注意事項】

  • 在中括號語法中,必須以字串形式指定屬性名,不能使用識別符號。
  • 中括號內可以使用字串,也可以使用字元型表示式,即只要表示式的值為字串即可。

範例3

下面範例使用 for/in 遍歷物件的可列舉屬性,並讀取它們的值,然後重寫屬性值。
for (var i in obj) {
    console.log(obj[i]);
    obj[i] = obj[i] + obj[i];
    console.log(obj[i]);
}
在上面程式碼中,中括號中的表示式 i 是一個變數,其返回值為 for/in 遍歷物件時列舉的每個屬性名。

3. 使用 Object.getOwnPropertyNames

使用 Object.getOwnPropertyNames() 函數能夠返回指定物件私有屬性的名稱。私有屬性是指使用者在本地定義的屬性,而不是繼承的原型屬性。具體用法如下:

Object.getOwnPropertyNames(object);

引數 object 表示一個物件,返回值為一個陣列,其中包含所有私有屬性的名稱。其中包括可列舉的和不可列舉的屬性和方法的名稱。如果僅返回可列舉的屬性和方法的名稱,應該使用 Object.keys() 函數。

範例4

在下面範例中定義一個物件,該物件包含三個屬性,然後使用 getOwnPropertyNames 獲取該物件的私有屬性名稱。
var obj = {x : 1, y : 2, z : 3};
var arr = Object.getOwnPropertyNames(obj);
console.log(arr);  //返回屬性名:x,yz

4. 使用 Object.keys

使用 Object.keys() 函數僅能獲取可列舉的私有屬性名稱。具體用法如下:

Object.keys(object);

引數 object 表示指定的物件,可以是 JavaScript 物件或 DOM 物件。返回值是一個陣列,其中包含物件的可列舉屬性名稱。

5. Object.getOwnPropertyDescriptor

使用 Object.getOwnPropertyDescriptor() 函數能夠獲取物件屬性的描述符。具體用法如下:

Object.getOwnPropertyDescriptor(object, propertyname);

引數 object 表示指定的物件,propertyname 表示屬性的名稱。返回值為屬性的描述符物件。

範例5

在下面範例中定義一個物件 obj,包含 3 個屬性,然後使用 Object.getOwnPropertyDescriptor() 函數獲取屬性 x 的資料屬性描述符,並使用該描述符將屬性 x 設定為唯讀。最後,呼叫 Object.defineProperty() 函數,使用資料屬性描述符修改屬性 x 的特性。遍歷修改後的物件,可以發現唯讀屬性 writable 為 false。
var obj = {x : 1, y : 2, z : 3};  //定義物件
var des = Object.getOwnPropertyDescriptor(obj, "x");  //獲取屬性x的資料屬性描述符
for (var prop in des) {  //遍歷屬性描述符物件
    console.log(prop + ':' + des[prop]);  //顯示特性值
}
des.writable = false;  //重寫特性,不允許修改屬性
des.value = 100;  //重寫屬性值
Object.defineProperty(obj, "x", des);  //使用修改後的資料屬性描述符覆蓋屬性x
var des = Object.getOwnPropertyDescriptor(obj, "x");  //重新獲取屬性x的資料屬性描述符
for (var prop in des) {  //遍歷屬性描述符物件
    console.log(prop + ':' + des[prop]);  //顯示特性值
}
一旦為未命名的屬性賦值後,物件就會自動定義該屬性的名稱,在任何時候和位置為該屬性賦值,都不需要定義屬性,而只會重新設定它的值。如果讀取未定義的屬性,則返回值都是 undefined。

刪除屬性

使用 delete 運算子可以刪除物件的屬性。

範例

下面範例使用 delete 運算子刪除指定屬性。
var obj = {x : 1};  //定義物件
delete obj.x;  //刪除物件的屬性x
console.log(obj.x);  //返回undefined
當刪除物件屬性之後,不是將該屬性值設定為 undefined,而是從物件中徹底清除屬性。如果使用 for/in 語句列舉物件屬性,只能列舉屬性值為 undefined 的屬性,但不會列舉已刪除屬性。

使用方法

方法也是函數,當函數被賦值給物件的屬性,就被稱為方法。方法的使用與函數是相同的,唯一的不同點是在方法內常用 this 參照呼叫物件,其實在普通函數內也有 this,只不過不常用。

使用點語法或中括號可以存取方法,使用小括號可以啟用方法。

範例1

與普通函數用法一樣,可以在呼叫方法時傳遞引數,也可以設計返回值。
var obj = {};
obj.f = function (n) {  //定義物件的方法
    return 10 * n;
}
var n = obj.f(5);  //呼叫方法,設定引數為5
console.log(n);  //返回值50

範例2

在方法內 this 總是指向當前呼叫物件。在下面範例中,當在不同執行環境中呼叫物件 obj 的方法 f() 時,該方法的 this 指向時不同的。
var obj = {  //定義物件
    f : function () {  //定義物件的方法
        console.log(this);  //存取當前物件
    }
}
obj.f();  //此時this指向物件obj
var f1 = obj.f;  //參照物件obj的方法f
f1();  //此時this指向物件window