都知道js是面向对象的,创建了对象后,对象中保存的就是一组组名值对,值可以是数据类型或函数。不管函数还是数据,都可以称为某某对象的属性。再细分,属性可以有两个类型:数据属性或访问器属性。
因此,数据属性不要误解为是数据的属性类型,函数的属性类型也是数据属性的。
var obj = {say:function(){return this.name;},age:11};
console.log(Object.getOwnPropertyDescriptors(obj));
//输出{value: ƒ, writable: true, enumerable: true, configurable: true}
数据属性(4个):
value: 大家熟知的一样,保存的是数据值,如果是函数,保留的就是整个函数。
writable: 是否可修改,设置为false可以巧妙定义出"私有变量"。true表示可修改,false则相反。
enumerable: 该属性是否可被枚举出。true表示可枚举,false则相反。
configurable: delete属性有没有用,能否修改value和enumerable属性,能否把属性改为访问器属性。true就是都可以,false就是都不可以。
访问器属性(4个):
configurable:同上
enumerable: 同上
get:一个用于访问其他属性值的函数
set:一个用于修改其他属性值的函数
对于这些属性类型,可以修改,用defineProperty()或defineProperties();可以读取,用getOwnPropertyDescriptor()或getOwnPropertyDescriptors()。当然,访问器属性只能用defineProperty()或defineProperties()创建。
一些细节:
var obj = {say:function(){return this.name;},age:11};
Object.defineProperty(obj,"name",{});
console.log(Object.getOwnPropertyDescriptors(obj));
//输出结果如下:
//age:{value: 11, writable: true, enumerable: true, configurable: true}
//name:{value: undefined, writable: false, enumerable: false, configurable: false}
//say:{value: ƒ, writable: true, enumerable: true, configurable: true}
可以看出,函数say是有value的数据属性;age是创建对象时定义的,所有属性特性都是true;name是用defineProperty()定义的,默认为数据属性,所有属性特性默认为false。
var obj = {age:11};
Object.defineProperty(obj,"age",{
configurable:false
});
Object.defineProperty(obj,"age",{
writable:false,
// enumerable:false, 会报错
// configurable:true, 会报错
value:12
});
Object.defineProperty(obj,"name",{
configurable:false, //如果不指定,默认也都是false
value:2
});
Object.defineProperty(obj,"name",{
// writable:false, 会报错
// enumerable:false, 会报错
// configurable:true, 会报错
// value:12 会报错
});
创建时定义的属性:修改了configurable后,其实还是可以修改writable和value属性的。
defineProperty()定义的属性:configurable一旦是false,以后就不可能在更改任何属性。
访问器属性暂时想到的,就是通过改变该属性改变内部多个属性。而且,如果某属性writable是false,访问器属性改变该属性会无效。