ECMAScript 5 爲 JavaScript 添加了大量新的對象方法,以下segmentfault
閱讀目錄數組
- Object.defineProperty(object, property, descriptor) // 添加或更改對象屬性
- Object.defineProperties(object, descriptors) // 添加或更改多個對象屬性
- Object.keys(object) // 以數組返回全部可枚舉的屬性
- Object.freeze(object) // 防止對對象進行任何更改
- Object.isFrozen(object) // 若是對象被凍結,則返回 true
- Object.getOwnPropertyDescriptor(object, property) // 訪問屬性
- Object.getOwnPropertyNames(object) // 以數組返回全部屬性
講述下列對象方法以前,有必要先了解下對象屬性相關的方法,有利於更能深入的熟悉對象方法函數
對象屬性描述符
概念:兩種主要形式分貝爲數據描述符和存取描述符;網站
數據描述符--是一個具備值的屬性,該值多是可寫的,也可能不是可寫的,包括configurable,enumerable,writable,value;this
存取描述符--是由getter-setter函數對描述的屬性,包括get和set方法,能夠代替value和writablespa
注:屬性描述符」對象只能在Object.defineProperty或Object.defineProperties中使用。code
Object.defineProperty(object, property, descriptor)
概念:用於在一個對象上定義一個新的屬性,或者修改一個對象現有的屬性,並返回這個對象對象
特色:使用Object.defineProperty()定義的屬性,默認是不能夠被修改,不能夠被枚舉,不能夠被刪除的,參考案例1;若要修改對象的屬性,須要經過設置屬性描述符可修改爲功,參考案例2;blog
注:設置set或者get,就不能在設置value和wriable,不然會報錯,參考案例3索引
案例1:
var obj = {}; Object.defineProperty(obj, 'name', { value: 'definePropertyTest' }); console.log('obj默認值:', obj); delete obj.name; console.log('obj刪除後:', obj); console.log('obj枚舉:', Object.keys(obj)); obj.name = 'definePropertyTest1'; console.log('obj修改後:', obj);
輸出結果
案例2:
var obj = {}; Object.defineProperty(obj, 'name', { value: 'definePropertyTest', writable: true, // 能夠被修改 enumerable: true, // 能夠被枚舉 configurable: true, // 能夠被刪除 }); console.log('obj默認值:', obj); console.log('obj枚舉:', Object.keys(obj)); obj.name = 'definePropertyTest1'; console.log('obj修改後:', obj); delete obj.name; console.log('obj刪除後:', obj);
輸出結果
案例3:
var obj = {}; Object.defineProperty(obj, 'name', { // value: 'definePropertyTest', // writable: true, 放開註釋則會報Invalid property descriptor. Cannot both specify accessors and a value or writable attribute enumerable: true, configurable: true, get: function () { console.log('get', this); return 'name ' + this.__name; }, set: function (newVal) { localStorage.setItem('name', newVal); console.log('set', newVal); this.__name = newVal; } }); console.log('obj默認值:', obj); obj.name = 'definePropertyTest'; console.log('obj枚舉:', Object.keys(obj)); delete obj.name; console.log('obj刪除後:', obj);
輸出結果
Object.defineProperties(object, descriptors)
概念:在對象上定義多個新的屬性或者修改多個原有屬性,返回修改後的目標對象
特色:與Object.defineProperties()方法相同,區別爲能夠對多個屬性進行定義和修改
案例:
var obj = {}; Object.defineProperties(obj, { name:{ enumerable: true, configurable: true, get: function () { return this.__name; }, set: function (newVal) { this.__name = 'definePropertyTest'; } }, age:{ enumerable: true, configurable: true, get: function () { return this.__age; }, set: function (newVal) { this.__age = '18'; } }, }); console.log('obj默認值:', obj); console.log('obj枚舉:', Object.keys(obj)); obj.name = 'definePropertyTest1'; obj.age = 19; console.log('修改後:', obj); //set方法進行了攔截,沒法修改 delete obj.name; delete obj.age; console.log('obj刪除後:', obj); //沒法刪除
輸出結果
Object.keys(object)
概念:返回對象的可枚舉屬性和方法,返回類型爲數組,數組中屬性名的排列順序和使用 for...in 循環遍歷該對象時返回的順序一致
注:在ES5裏,若是此方法的參數不是對象(而是一個原始值),那麼它會拋出 TypeError。在ES2015中,非對象的參數將被強制轉換爲一個對象
案例:
var obj = { key1:1,key2:2 } console.log(Object.keys(obj)) //['key1','key2'] //傳入數組或字符串,返回索引 var arr = ['key1','key2']; var string = "key"; console.log(Object.keys(arr)) //["0","1"] console.log(Object.keys(string)) //["0","1","2"] //傳入構造函數 返回空數組或者屬性名 function TestObjectKey(name,age){ this.name = name; this.age = age; this.toString = function(){ return 'toString'; } } console.log(Object.keys(TestObjectKey)); //[] var key = new TestObjectKey("key1",18); console.log(Object.keys(key)); // ["name", "age", "toString"]
Object.freeze(object)
概念:凍結一個對象,返回和傳入的參數相同的對象
特色:凍結的對象不能被修改,不能向對象添加新的屬性,不能刪除已有屬性,不能修改屬性的性質包括可枚舉性、可配置性、可寫性、以及不能修改已有屬性的值,該對象的原型也不能修改
注:凍結對象不是常量對象(淺凍結)
案例:
const obj1 = { name:"freeze1" } Object.freeze(obj1); const obj2 = Object.freeze(obj1); console.log(obj1===obj2); //true 返回原來的對象 obj1.name = "freeze1"; console.log(obj1); //{name:"freeze1"} 凍結的對象不可更改 delete obj1.name console.log(obj1); //{name:"freeze1"} 凍結的對象不可刪除 obj1.age = 18; console.log(obj1) //{name:"freeze1"} 凍結的對象不可添加屬性 const obj3 = { internal:{} } Object.freeze(obj3); obj3.internal.name = "freeze3"; console.log(obj3) //{internal:{name:freeze3}} 凍結的對象不是常量對象-淺凍結 var arr = ["freeze"]; Object.freeze(arr); arr[1] = "freeze1"; console.log(arr) //凍結的數組不能修改,其它同對象
Object.isFrozen(object)
概念:返回給定對象是否凍結的Boolean
特色:一個對象默認是非凍結的,凍結的對象不可擴展,不可配置
案例:
var obj = {}; console.log(Object.isFrozen(obj)); //空對象默認是非凍結的 var obj1 = { name:'isFrozen' } console.log(Object.isFrozen(obj1)); //非空對象默認是非凍結的 var obj2 = Object.freeze(obj); console.log(Object.isFrozen(obj)); //true 凍結對象是凍結的 console.log(Object.isFrozen(obj2)); //true 凍結對象的拷貝也是凍結的
Object.getOwnPropertyDescriptor(object, property)
概念:返回指定對象上一個自有屬性對應的屬性描述符
案例:
var obj = {name:"getOwnPropertyDescriptor"} Object.getOwnPropertyDescriptor(obj,"name"); // { // value: "getOwnPropertyDescriptor", // writable: true, // enumerable: true // configurable:true // } var obj1 = {}; Object.defineProperty(obj1, "name", { value: "getOwnPropertyDescriptor", writable: false, enumerable: false }); Object.getOwnPropertyDescriptor(obj1, "name"); // { // value: "getOwnPropertyDescriptor", // writable: false, // enumerable: false, // configurable:false // }
Object.getOwnPropertyNames(object)
概念:返回一個由指定對象的全部自身屬性的屬性名組成的數組
案例:
var obj = {}; Object.getOwnPropertyNames(obj); //[] var arr = ["a","b","c"]; Object.getOwnPropertyNames(arr); //["0", "1", "2", "length"]
參考網站https://segmentfault.com/a/1190000019446677