前言
在当前面向对象语言的盛行的时代,理解对象的属性可以说是掌握面向对象思想必不可少的一步。
通过阅读js高级程序设计的第六章第一节我们可以了解到:
ECMA-262第五版在定义只有内部才用的特性时,描述了属性的各种特征。
这些特性是为了实现js引擎用的,因此不能在js中直接访问这些特性。为了表示特性时内部值,故这些特性使用[[ ]]包裹,以示规范。
在ECMAScript中有两种属性,数据属性和访问器属性
数据属性
何为数据属性?
数据属性包含一个数据值的位置,在这个位置可以读取和写入值。(我们常常通过工厂模式创建对象的时候添加的属性通常就是这种类型)
数据属性包含4个描述其行为的特性。
[[configurable]]:表示能否通过delete删除属性从而重新定义属性。能否修改属性的特性,或者能否把属性修改成访问器的属性。默认为true.
[[Enumerable]]:表示能否通过for-in循环返回属性。默认为true;
[[Value]]: 包含这个属性的数据值。读取属性值的时候,从这个位置读,写入属性值的时候,把新值保存在这个位置。这个特性的默认值为undefined。
[Writable]]:表示能否修改属性的值。默认为true。
这些特性可以通过Object.defineProperty()来修改。
这个方法要接受三个参数:属性所在的对象,属性的名字和一个描述符对象。其中描述符对象必须是上面的4个特性,可以设置其中的一个或多个值,可以修改对应的特性值。
注意:
当特性被修改后,例如writable设置为false;那么我们的属性值就不能修改了,在严格模式下修改还会抛出错误。此外,如果configurable设置成了false;(属性不可配置),那么就不能设置成true了。此时调用defineProperty()修改除了writable之外的特性,都会导致错误。
下面我们用代码来简单了解一下这些特性的用法及表现
//以常见类型为例 创建一个包含name,age,sex的对象
var person = {
name: "xiaoming",
age: 21,
sex:"man"
};
//此方法需要三个参数(被操作对象,对象的数据属性,描述符对象)
Object.defineProperty( person, "name", {
enumerable: false,
value: "起亚"
}); //设置person中的name数据属性的可枚举性为false,即不能被for-in循环
console.log(person);
for(var key in person) {
console.log(key); //我们通过遍历输出可以发现name并未被打印出来
}
Object.defineProperty( person, "sex", {
writable: false
}); //修改sex数据属性的可写性为false; 表示sex属性不可改变
person.sex = "woman";
console.log(person.sex); //21
Object.defineProperty(person, "age", {
configurable: false,
writable: false,
value: 22
}); //这里我们对数据属性age的可配置修饰符[[configurable]]设置成了false,表示之后不可再对当前的age做任何修饰符上的变动.不能删除这个属性
delete person.age;
person.age = 33;
console.log(person); //我们输出的对象的age属性仍然存在且其值是在最后一次配置里的22而非33.
这种写法看上去很繁琐,我们必须对单一的属性一一设置,这大大的增加了我们的代码量。也肯定不是我们想要的效果。因此,在有设置多个属性的情况下,我们可以使用Object的另一个方法 ----- Object.defineProperities();
示例代码
var person = {
name: "xiaoming",
age: 21,
sex:"man"
};
console.log(person.name,person.age,person.sex);
Object.defineProperties( person, {
name: {
enumerable: false,
},
age: {
writable: false,
value: 22
},
sex: {
writable: false,
configurable: false
}
});
person.name = "起亚";
person.age = 33;
person.sex = "woman";
delete person.sex;
console.log(person.name,person.age,person.sex);
console.log(person); //通过输出可以发现我们配置之后的修改都不在生效了
以上就是我关于对象数据属性的一点个人理解,有关访问器属性的内容会在下次分享交流。