对象属性的扩展
使用.的形式动态添加(不可指定属性描述符)
使用Object.defineProperty的形式来添加(可以指定属性描述符)
获取对象属性的描述符
Object.getOwnPropertyDescriptor(obj,"name");
属性描述符
writable:属性值的修改的权限
true:属性值是可以修改的
false:属性值是不可以修改的
默认情况下静默失败
严格模式下报错
configable:属性的重定义与删除权限
true:属性是可以重新定义和删除的
false:属性是不可以重新定义和删除的
默认情况和严格模式下都会报错
false情况下writable由true转成false是合理的,不会报错
emumerable:属性的枚举权限(能不能出现在for in循环中)
true:属性是可以重新定义和删除的
false:属性是不可以重新定义和删除的
默认情况和严格模式下都会报错
set&get
get 方法控制着属性的读取操作
set 方法控制着属性的赋值操作
拥有get或set方法,或两者都有的属性,我们称之为访问描述符(与数据描述符相对应)
访问描述符与writable是会冲突的
不变性
常量属性
将属性的writable和configurable设置为false
禁止属性的扩展
Object.preventExtensions(obj);
密封
Object.seal(obj)
在禁止对象扩展的基础上把现有属性的configurable都调整为false
冻结
Object.freeze(obj)
在密封对象的基础上把现有属性的writable都调整为false
注意
js所有的方法都只会影响对象的直接属性
判断枚举(不会遍历原型链)
obj.propertyIsEnumerable("a")
获取对象所有的可枚举属性(不会遍历原型链)
Object.keys(obj)
获取对象所有的属性(不会遍历原型链)
obj.getOwnPropertyNames("a")
存在性检查
(会遍历原型链)in操作符
(不会遍历原型链,只在对象中查找)obj.hasOwnProperty("a);
属性的查找
1.在对象中查找是否具有相同名称的属性,如果找到,就会返回这个属性的值。
2.如果没有找到,则遍历原型链
3.无论·如何都没找到,返回undefined
属性的设置
1.如果属性直接存在于对象中 不在原型链上
找到直接存在于对象中的属性
-数据描述符(没有setter/getter)
直接修改对象中的属性(注意writbale的值)
-访问描述符
直接调用set方法
2.如果属性不直接存在于对象中也不在原型链上
在对象的直接属性中添加一个属性(数据描述符)
value:"a"
writable:true
configurable:true
enumerable:true
3.如果属性不直接存在于对象中 在原型链上
①.该属性是数据描述符(没有setter/getter)
-writbale为true
直接在对象中添加一个属性,我们称之为屏蔽属性
-writbale为false
报错,不会生成屏蔽属性
②.该属性是访问描述符
调用set,不会生成屏蔽属性
4.如果属性直接存在于对象中 也在原型链上
找到直接存在于对象中的属性
-数据描述符(没有setter/getter)
直接修改对象中的属性(注意writbale的值)
-访问描述符
直接调用set方法