JavaScript 語言核心(7)ECMAScrpt 5 物件與特性操作
|
JavaScript 語言核心(6)鍵值聚合體的物件 << 前情 在 JavaScript 中,物件基本上是鍵值的聚合體,你幾乎可以自由地修改物件,然而,如果你有個物件不想要被自由修改的話,則必須透過各種設計來限制相關特性。 ECMAScript 5 中對物件的特性(Properties)擴充或修改等提供了新的 API,特性本身也有了更豐富的描述,你仍然擁有修改物件的自由度,然而,在不需要這種自由度時,你也可以在嚴格模式之下加以限制。 限定物件的擴充在 ECMAScript 5 中,提供了 'use strict'
var obj1 = {};
console.log(Object.isExtensible(obj1)); // true
obj1.name = 'caterpillar';
var obj2 = Object.preventExtensions(obj1);
console.log(obj1 === obj2); // true
console.log(Object.isExtensible(obj1)); // false
obj1.age = 39; // TypeError
被標示為無法擴充的物件,只是無法再增添特性,不過仍然可以用 'use strict'
var obj = {name : 'caterpillar'};
Object.preventExtensions(obj);
obj.name = 'Justin';
console.log(obj.name); // Justin
delete obj.name;
console.log(obj.name); // undefined
Object.prototype.name = 'caterpillar';
console.log(obj.name); // caterpillar
在 ECMAScript 5 中,物件一但被 特性描述器想要進一步限定物件的特性可否修改、刪除等,必須透過 ECMAScript 5 新增的其他 API,不過在這之前,你必須認識 ECMAScript 5 中定義的特性描述器(Property descriptor)。 不同於過去物件上的特性,單純只是一對名稱與值,ECMAScript 5 中物件上每個特性,都會有
這幾個屬性合在一起,又稱為資料描述器(Data descriptor),為特性描述器的一部份,可以使用 如果你直接於物件上新增特性,那麼 'use strict'
var obj = {name : 'caterpillar'};
console.log(JSON.stringify(
Object.getOwnPropertyDescriptor(obj, 'name')
));
上面這個範例執行之後,會顯示 {“value":"caterpillar","writable":true,"enumerable":true,"configurable":true}。 Object.defineProperty、Object.defineProperties你可以使用 'use strict'
var obj = {};
Object.defineProperty(obj, 'name', {
value : 'caterpillar',
writable : false,
enumerable : false,
configurable : false
});
console.log(JSON.stringify(
Object.getOwnPropertyDescriptor(obj, 'name')
));
執行以上範例,會顯示 {“value":"caterpillar","writable":false,"enumerable":false,"configurable":false},事實上,如果你使用 'use strict'
var obj = {};
Object.defineProperty(obj, 'name', {
value : 'caterpillar'
});
console.log(JSON.stringify(
Object.getOwnPropertyDescriptor(obj, 'name')
));
然而,以下會顯示 {“value":"caterpillar","writable":true,"enumerable":false,"configurable":true},除了 'use strict'
var obj = {name : 'caterpillar'};
Object.defineProperty(obj, 'name', {
enumerable: false
});
console.log(JSON.stringify(
Object.getOwnPropertyDescriptor(obj, 'name')
));
如果有多個特性要設定,可以使用 'use strict'
var obj = {};
Object.defineProperties(obj, {
'name': {
value : 'John',
enumerable : true
},
'age': {
value : 39,
writable : true,
enumerable : true
},
});
如果特性的 實際上,你還可以使用 'use strict'
var obj = {};
Object.defineProperty(obj, 'name', {
get : function(){ return this.__name__; },
set : function(value){ this.__name__ = value.trim(); },
enumerable : true
});
Object.defineProperty(obj, '__name__', {
writable : true,
enumerable : false
});
obj.name = ' Justin ';
console.log('*' + obj.name + '*'); // *Justin*
for(var p in obj) {
console.log(p); // 只會顯示 name
}
注意,如果你定義了 如果物件被 seal 與 freeze基於 Object.seal = function(obj) {
Object.getOwnPropertyNames(obj)
.forEach(function(prop) {
var desc = Object.getOwnPropertyDescriptor(obj, prop);
desc.configurable = false;
Object.defineProperty(obj, prop, desc);
});
return Object.preventExtensions(obj);
};
被彌封的物件,仍然可以修改現有的特性值,如果連特性值都不能被修改,只想作為一個唯讀物件,那麼可以使用 Object.freeze = function(obj) {
Object.getOwnPropertyNames(obj)
.forEach(function(prop) {
var desc = Object.getOwnPropertyDescriptor(obj, prop);
if('value' in desc) { // 排除設定了 get 與 set 的情況
desc.writable = false;
}
desc.configurable = false;
Object.defineProperty(obj, prop, desc);
});
return Object.preventExtensions(obj);
};
|

Java 學習之路





