JavaScript ES5 Object Methods and object property meta data

 

一、object property meta data

在 ES5 裡,每一物件的每一個屬性都自己的 property meta data,

分別是 Value、Writable、Enumerable、Configurable。

可以使用 Object.defineProperty 與 Object.defineProperties 方法去新增其 property meta data。

 

1、value

指的是一個屬性的屬性值。

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

Object.defineProperty(person, "age", {
    value: 18
});

console.log(person.age);

其結果為

 

2、writable

該屬性能否被修改。

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

Object.defineProperty(person, "age", {
    value: 18,
    writable: false
});

person.age = 3;
console.log(person.age);

其結果為

 

3、enumerable

該屬性是否可被列舉出來。

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

Object.defineProperty(person, "age", {
    value: 18,
    enumerable: false
});

console.log(Object.keys(person));

其結果為

如果一物件於初始建構時就擁有屬性,則該屬性的 enumerable 預設值為 true,

如果是使用 defineProperty 額外新增的話,則該屬性的 enumerable 預設值為 false。

 

4、configurable

該屬性是否可被重複定義。

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};
Object.defineProperty(person, "age", {
    value: 18
});

Object.defineProperty(person, "age", {
    value: "20"
});

其結果為

 

總結特性:

當我們一般使用 new 關鍵字或 Object Literal 建立物件時 writable、configurable、enumerable 預設為 true,

而當使用 Object.defineProperty 建立物件屬性時,writable、configurable、enumerable 則預設為 false。

var car = new Object();
car.name = "BMW";
console.log(Object.getOwnPropertyDescriptor(car, "name"));

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};
Object.defineProperty(person, "age", {
    value: 18
});
console.log(Object.getOwnPropertyDescriptor(person, "language"));
console.log(Object.getOwnPropertyDescriptor(person, "age"));

其結果為

 

二、Object.defineProperty(object object, string propertyName, object descriptor)

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

Object.defineProperty(person, "language", { value: "NO" });
console.log(person.language);

說明:

利用 Object.defineProperty 方法,來對一物件新增一屬性與屬性值。

 

三、Object.defineProperties(object object, object descriptors)

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

Object.defineProperties(person, {
    age: {
        value: 18
    },
    sex: {
        value: 'female'
    }
});
console.log(person.age, person.sex);

結果如下

說明:

利用 Object.defineProperties 方法,來對一物件新增多個屬性與與屬性值。

 

四、Object.getOwnPropertyDescriptor(object object, string propertyName)

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

var desc = Object.getOwnPropertyDescriptor(person, "language");
console.log(desc);

結果如下

說明:

利用 Object.getOwnPropertyDescriptor 方法,來對一物件的某屬性,去取得其 property meta data。

 

五、Object.getOwnPropertyNames(object object)

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};
var desc = Object.getOwnPropertyNames(person);
console.log(desc);

結果如下

說明:

利用 Object.getOwnPropertyNames 方法,取得一物件的所有屬性名稱,並以陣列型式回傳。

 

六、Object.keys(object object)

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

Object.defineProperty(person, "age", {
    value: 18,
    enumerable: true
});

console.log(Object.keys(person));

結果如下

說明:

利用 Object.keys 方法,來取得一物件之所有 enumerable meta data 值為 true 的屬性名稱,

並以陣列型式回傳。

 

七、Object.getPrototypeOf(object object)

var Show = function () { return "Show"; };
var o = new Show();
var result = Object.getPrototypeOf(o);
console.log(result);

結果如下

說明:

取得一物件的 Prototype。

 

八、Object.preventExtensions(object object)

使其物件不能再被添加新屬性。

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

Object.isExtensible(person);

Object.preventExtensions(person);

Object.isExtensible(person);

Object.defineProperty(person, "age", {
    value: 18
});

結果如下

 

九、boolean Object.isExtensible(object object)

用來判斷一物件是否可被添加新屬性,範例同上。

 

十、Object.seal(object object)

使其物件不能再被添加新屬性(Object.preventExtensions()),並且所有屬性不可被重複定義(configurable: false)。

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

console.log(Object.isExtensible(person));
console.log(Object.getOwnPropertyDescriptor(person, "firstName"));
console.log(Object.getOwnPropertyDescriptor(person, "lastName"));

Object.seal(person);
console.log(Object.isSealed(person));

console.log(Object.isExtensible(person));
console.log(Object.getOwnPropertyDescriptor(person, "firstName"));
console.log(Object.getOwnPropertyDescriptor(person, "lastName"));

Object.defineProperty(person, "age", {
    value: 18
});

結果如下

 

十一、boolean Object.isSealed(object object)

用來判斷一物件是否為 seal 狀態,範例同上。

 

十二、Object.freeze(object object)

使其物件不能再被添加新屬性(Object.preventExtensions()),

並且所有屬性不可被重複定義(configurable: false),

並且所有屬性值也不能被更動(writable: false)。

var person = {
    firstName: "John",
    lastName: "Doe",
    language: "EN"
};

console.log("isExtensible: " + Object.isExtensible(person));
console.log("isSealed: " + Object.isSealed(person));
console.log(Object.getOwnPropertyDescriptor(person, "firstName"));
console.log(Object.getOwnPropertyDescriptor(person, "lastName"));

Object.freeze(person);
console.log("isFrozen: " + Object.isFrozen(person));

console.log("isExtensible: " + Object.isExtensible(person));
console.log("isSealed: " + Object.isSealed(person));
console.log(Object.getOwnPropertyDescriptor(person, "firstName"));
console.log(Object.getOwnPropertyDescriptor(person, "lastName"));

結果如下

 

十三、boolean Object.isFrozen(object object)

用來判斷一物件是否為 freeze 狀態,範例同上。