同个物件内的单一属性编辑:configurable、writable、enumerable、value
Object.defineProperty(物件,'属性' , {程式码:想调整的参数})
var a = { A: '1', B: '2', C: '3', }; console.log(a); //{A: '1', B: '2', C: '3'} Object.defineProperty(a, 'A', { //注意属性为字串型 configurable: true, //代表目标属性可被删除 writable: true, //代表目标属性的值可被覆写 enumerable: true, //代表目标属性可被列举 value: '2', //A属性的值变更为2 }); console.log(a); Object.defineProperty(a, 'A', { configurable: true, writable: false, //代表不可被覆盖 enumerable: true, value: '3', }); console.log(a); //A属性的值维持为2 Object.defineProperty(a, 'B', { configurable: true, //代表B可以被删除 }); Object.defineProperty(a, 'A', { configurable: false, //代表A不可以被删除 }); delete a.B; delete a.A; console.log(a); //{A: '2', C: '3'} for (var key in a) { //利用for in 列举物件A的内部属性 console.log(key) //A C }; Object.defineProperty(a, 'C', { enumerable: false, //代表属性C不可被列举 }); for (var key in a) { console.log(key) //A };
var a = { A: '1', B: '2', C: '3', }; console.log(a); //{A: '1', B: '2', C: '3'} Object.defineProperty(a, 'D', { //a物件下新增新属性D,值是空物件{} value: {}, }); console.log(a); //{A: '1', B: '2', C: '3', D: {…}} Object.defineProperty(a, 'D', { writable: false, }); a.D = 7; console.log(a.D); //{} a.D.d = '9'; console.log(a.D); //依照物件及物件属性在记忆体建立及读取address的特性,{d: '9'}
原型物件及自订原型的enumerable:
function person() { }; person.prototype.name = 'Tom'; var TOM = new person(); TOM.father = 'BOB'; TOM.name = 'Mat'; console.log(TOM); //person {father: 'BOB', name: 'Mat'} for (var key in TOM) { console.log(key); }; //father name console.log(TOM.hasOwnProperty('father')); //true console.log(TOM.hasOwnProperty('name')); //true
去掉TOM.name = 'Mat'后,依然可以用for in列举出name,而此时的name属于自订的原型person的属性。
function person() { }; person.prototype.name = 'Tom'; var TOM = new person(); TOM.father = 'BOB'; console.log(TOM); //person {father: 'BOB'} for (var key in TOM) { console.log(key); }; //father name console.log(TOM.hasOwnProperty('father')); //true console.log(TOM.hasOwnProperty('name')); //false 子层的TOM物件没有name属性,故false
解决方式:利用Object.defineProperty修改自订原型的enumerable,且浏览器的name颜色也会改成跟原生原型一样。
Object.defineProperty(person.prototype, 'name', { enumerable: false, });
同个物件内的多个属性编辑:Object.defineProperties
var a = { A: '1', B: '2', C: '3', }; console.log(a); Object.defineProperties(a, { A: { //不用再用字串型 value: '7', }, B: { value: '8', }, }); console.log(a);
检查物件内属性的4个特性:
利用Object.getOwnPropertyDescriptor(物件,'属性')
var a = { A: '1', B: '2', C: '3', }; console.log(a); Object.defineProperties(a, { A: { value: '7', }, B: { value: '8', }, }); console.log(Object.getOwnPropertyDescriptor(a, 'A'));
物件的操作:只针对物件本身,对于物件内部属性的次要物件(值),则没有效果。
1. preventExtensions
2. seal
3. Freeze
var a = { A: '1', B: '2', C: {}, }; console.log(Object.isExtensible(a)); //true Object.preventExtensions(a); console.log(Object.isExtensible(a)); //变为false a.A = '7'; console.log(a); //可以变更值:{A: '7', B: '2', C: {…}} delete a.A; console.log(a); //可以删除属性A:{B: '2', C: {…}} a.D = 'd'; console.log(a); //无法新增属性D:{B: '2', C: {…}} a.C.c = 'DC'; console.log(a); //可以增加属性C里面的值(物件): {c: 'DC'}
物件的操作
preventExtensions2. seal
Freeze拥有preventExtensions的特性,加上无法删除或新增属性、无法编辑属性的2个特徵,仅能变更属性的值。
var a = { A: '1', B: '2', C: {}, }; console.log(a); //{A: '1', B: '2', C: {…}} console.log(Object.getOwnPropertyDescriptor(a, 'A')); //{value: '1', writable: true, enumerable: true, configurable: true} console.log(Object.isExtensible(a)); //true console.log(Object.isSealed(a)); //false Object.seal(a); console.log(Object.isExtensible(a)); //拥有preventExtensions的特性,所以为false console.log(Object.isSealed(a)); //true console.log(Object.getOwnPropertyDescriptor(a, 'A')); //{value: '1', writable: true, enumerable: true, configurable: false} a.A = '7'; console.log(a); //{A: '7', B: '2', C: {…}} delete a.A; console.log(a); //{A: '7', B: '2', C: {…}},无法删除属性A a.D = 'd'; console.log(a); //{A: '7', B: '2', C: {…}},无法新增属性D a.C.c = 'DC'; console.log(a); //C: {c: 'DC'} Object.defineProperty(a, 'B', { writable: false, }); console.log(Object.getOwnPropertyDescriptor(a, 'B')); //{value: '2', writable: false, enumerable: true, configurable: false} Object.defineProperty(a, 'B', { enumerable: false, }); //报错 Object.defineProperty(a, 'B', { configurable: true, }); //报错
物件的操作
preventExtensionsseal3. Freeze
拥有前2者的特性,加上无法调整属性的值。
var a = { A: '1', B: '2', C: {}, }; console.log(a); //{A: '1', B: '2', C: {…}} Object.freeze(a); console.log(Object.isExtensible(a)); //false console.log(Object.isSealed(a)); //true console.log(Object.isFrozen(a)); //true console.log(Object.getOwnPropertyDescriptor(a, 'B')); //{value: '2', writable: false, enumerable: true, configurable: false} a.A = '7'; console.log(a); //{A: '1', B: '2', C: {…}} delete a.A; console.log(a); //{A: '1', B: '2', C: {…}} a.D = 'd'; console.log(a); //{A: '1', B: '2', C: {…}} a.C.c = 'DC'; console.log(a); //C: {c: 'DC'} Object.defineProperty(a, 'B', { writable: true, }); //报错 Object.defineProperty(a, 'B', { enumerable: false, }); //报错 Object.defineProperty(a, 'B', { configurable: true, }); //报错