属性描述符
众所周知,javascript的三大组成部分:
1,ECMAScript
2,DOM
3,BOM
这里,重点介绍ECMAScript中的对象的属性描述符
属性描述符:
1,value —— 属性的字面值
2,writable —— 可写性
3,enumerable —— 可枚举性
4,configurable —— 可配置性
后三个都只能取布尔值:true false,默认都是true,即可写、可枚举、可配置
常见用途:
1,通过给原型对象添加不可枚举的方法,这样使它们更像内置方法
2,给对象定义不可修改或删除的属性,进而锁定对象
writable - 可写性
表示: 属性是否可修改,和删除属性无关。
> let obj = new Object({name: "CJH"});
> Object.getOwnPropertyDescriptor(obj, "name");
{ value: 'CJH', // 默认都为true
writable: true,
enumerable: true,
configurable: true }
> Object.defineProperty(obj, "name", {writable: false}); // 设置为不可写
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'CJH',
writable: false, // name属性不可写
enumerable: true,
configurable: true }
> obj
{ name: 'CJH' }
> obj.name = "JS"
> obj
{ name: 'CJH' } // name值不可修改
> delete obj.name; // 但是,name属性可以删除
true
> obj
{}
enumerable - 可枚举性
表示: 属性存在,只是不可枚举,和修改删除无关
> let obj = {name: "ECMA"};
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'ECMA',
writable: true,
enumerable: true,
configurable: true }
> Object.defineProperty(obj,"name",{enumerable: false});
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'ECMA',
writable: true,
enumerable: false, // 设置为不可枚举
configurable: true }
> obj.name // 属性表达式正常读取
'ECMA'
> "name" in obj // in 操作符判断正确
true
> Object.keys(obj); // keys()方法无法枚举该属性
[]
> obj
{}
可配置性
用于控制其他特性的是否可以被修改,但规则比较复杂。
1,不可配置时,不可再修改属性的配置性和枚举性
> obj
{ name: 'ECMA', age: 1 }
> Object.defineProperty(obj,"name",{configurable: false}); // 设置为不可配置
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'ECMA',
writable: true,
enumerable: true,
configurable: false } // 设置成功
> Object.defineProperty(obj,"name",{configurable: true}); // 再修改可配置性则报错
TypeError: Cannot redefine property: name
at Function.defineProperty (<anonymous>)
> Object.defineProperty(obj,"name",{enumerable: false}); // 修改枚举性则报错
TypeError: Cannot redefine property: name
at Function.defineProperty (<anonymous>)
2,不可配置时,可写性只能从true修改为false,否则报错
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'ECMAScript',
writable: true, // 当前为可写
enumerable: true,
configurable: false } // 当前为不可配置
> Object.defineProperty(obj,"name",{writable: false}); // 成功,不报错
> Object.defineProperty(obj,"name",{writable: true}); // 失败,报错
TypeError: Cannot redefine property: name
at Function.defineProperty (<anonymous>)
3,不可写且不可配置,才表示属性值不可修改;不可写且可配置,表示属性值可修改(实际上是修改了value值,再设置为不可写)
> let obj = {name: "ECMAScript"};
> Object.defineProperty(obj,"name",{configurable: false}); // 设置为不可配置
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'ECMAScript',
writable: true, // 可修改
enumerable: true,
configurable: false } // 不可配置
> obj.name = "ECMA"; // 修改属性值
'ECMA'
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'ECMA', // 属性值修改成功
writable: true,
enumerable: true,
configurable: false }
> Object.defineProperty(obj,"name",{writable: false}); // 修改为不可写
> obj.name = "JS"; // 修改属性值
'JS'
> Object.getOwnPropertyDescriptor(obj,"name");
{ value: 'ECMA', // 属性值修改失败
writable: false,
enumerable: true,
configurable: false }
>
关于以上涉及的方法:
1,Object.defineProperty(obj,“name”,{configurable: false}); 设置属性的特性
2,Object.getOwnPropertyDescriptor(obj,“name”); 查看自有属性的描述符
3,Object.keys(obj); 获取对象的所有枚举属性名列表
对象的其他相关方法:
obj.hasOwnProperty(“name”); 判断obj对象中是否含自有属性name
obj.propertyIsEnumerable(“name”); true表示name是obj的属性,且可枚举
Object.getOwnPropertyNames(obj); 获取对象的所有自有属性名列表
记录自:JavaScript权威指南(第6版)