雖然說現在並不是所有的瀏覽器都已經支援ECMAScript5的新特性,但相比於ECMAScript4而言ECMAScript5被廣大瀏覽器廠商廣泛接受,目前主流的瀏覽器中只有低版本的IE不支援,其它都或多或少的支援了ECMAScript5的新特性,其中重中之重自然是一切物件的基型別——Object
Object.create(prototype[,descriptors])
這個方法用於建立一個物件,並把其prototype屬性賦值為第一個引數,同時可以設定多個descriptors,關於decriptor下一個方法就會介紹這裡先不說。只需要這樣就可以建立一個原型鏈乾淨物件了
var o = Object.create({ "say": function () { alert(this.name); }, "name":"Byron" });
Object.defineProperty(O,Prop,descriptor) / Object.defineProperties(O,descriptors)
想明白這兩個函式必須明白descriptor是什麼,在之前的JavaScript中物件欄位是物件屬性,是一個鍵值對,而在ECMAScript5中引入property,property有幾個特徵
1. value:值,預設是undefined
2. writable:是否是隻讀property,預設是false,有點像C#中的const
3. enumerable:是否可以被列舉(for in),預設false
4. configurable:是否可以被刪除,預設false
同樣可以像C#、Java一樣些get/set,不過這兩個不能和value、writable同時使用
5.get:返回property的值得方法,預設是undefined
6.set:為property設定值的方法,預設是undefined
Object.defineProperty(o,'age', { value: 24, writable: true, enumerable: true, configurable: true }); Object.defineProperty(o, 'sex', { value: 'male', writable: false, enumerable: false, configurable: false }); console.log(o.age); //24 o.age = 25; for (var obj in o) { console.log(obj + ' : ' + o[obj]); /* age : 25 //沒有把sex : male 遍歷出來 say : function () { alert(this.name); } name : Byron */ } delete o.age; console.log(o.age);//undefined console.log(o.sex); //male //o.sex = 'female'; //Cannot assign to read only property 'sex' of #<Object> delete o.age; console.log(o.sex); //male ,並沒有被刪除
也可以使用defineProperties方法同時定義多個property,
Object.defineProperties(o, { 'age': { value: 24, writable: true, enumerable: true, configurable: true }, 'sex': { value: 'male', writable: false, enumerable: false, configurable: false } });
Object.getOwnPropertyDescriptor(O,property)
這個方法用於獲取defineProperty方法設定的property 特性
var props = Object.getOwnPropertyDescriptor(o, 'age'); console.log(props); //Object {value: 24, writable: true, enumerable: true, configurable: true}
Object.getOwnPropertyNames
獲取所有的屬性名,不包括prototy中的屬性,返回一個陣列
console.log(Object.getOwnPropertyNames(o)); //["age", "sex"]
例子中可以看到prototype中的name屬性沒有獲取到
Object.keys()
和getOwnPropertyNames方法類似,但是獲取所有的可列舉的屬性,返回一個陣列
console.log(Object.keys(o)); //["age"]
上面例子可以看出不可列舉的sex都沒有獲取的到
Object.preventExtensions(O) / Object.isExtensible
方法用於鎖住物件屬性,使其不能夠擴充,也就是不能增加新的屬性,但是屬性的值仍然可以更改,也可以把屬性刪除,Object.isExtensible用於判斷物件是否可以被擴充
console.log(Object.isExtensible(o)); //true o.lastName = 'Sun'; console.log(o.lastName); //Sun ,此時物件可以擴充 Object.preventExtensions(o); console.log(Object.isExtensible(o)); //false o.lastName = "ByronSun"; console.log(o.lastName); //ByronSun,屬性值仍然可以修改 //delete o.lastName; console.log(o.lastName); //undefined仍可刪除屬性 o.firstname = 'Byron'; //Can't add property firstname, object is not extensible 不能夠新增屬性
Object.seal(O) / Object.isSealed
方法用於把物件密封,也就是讓物件既不可以擴充也不可以刪除屬性(把每個屬性的configurable設為false),單數屬性值仍然可以修改,Object.isSealed由於判斷物件是否被密封
Object.seal(o); o.age = 25; //仍然可以修改 delete o.age; //Cannot delete property 'age' of #<Object>
Object.freeze(O) / Object.isFrozen
終極神器,完全凍結物件,在seal的基礎上,屬性值也不可以修改(每個屬性的wirtable也被設為false)
Object.freeze(o); o.age = 25; //Cannot assign to read only property 'age' of #<Object>
最後
上面的程式碼都是在Chrome 29下一嚴格模式(’use strict’)執行的,而且提到的方法都是Object的靜態函式,也就是在使用的時候應該是Object.xxx(x),而不能以物件例項來呼叫。總體來說ES5新增的這些方法為javaScript物件導向設計提供了進一步的可配置性,用起來感覺很不錯。