今天说一下js 的属性设置,ES5中定义了两种属性,数据属性和访问器属性(getter 和 setter)下面我总结了一些数据属性 和 访问器属性的一些知识点。
一、数据属性
数据属性有四个描述其行为的特征:
- [[Configurable]]: 表示能否被 delete 删除,默认为 true
- [[Enumerable]]: 表示能否通过 for - in 循环返回属性, 默认为true
- [[Writable]]: 表示能否修改这个属性的数据值,默认为true
- [[Value]] : 包含这个属性的值,读取属性值时,从这个位置读,写入时从这个位置写入。
注意:要修改属性的特性,要用ES5的 Object.defineProperty()来定义
该方法有三个参数,第一个为要处理的对象(注意不要带引号),第二个为要处理的属性名,第三个为一个对象,用于处理属性。
例如:
var person = {
_name:"Jhone", // 前面加下横线 ,下面会讲
sex:"man",
age:24,
height:170,
}
person.fun = function () {
console.log("my monthds")
}
Object.defineProperty(person,"name",{
configurable:false, // 设置为通过delete 不能删除
enumerable:false, // 设置为通过for - in 循环不能返回该属性
writable:false, // 设置为不能修改属性值
// value: 包含这个属性的数据值,能写入,能读取
});
结果测试:
delete(person.name);
delete(person.sex);
console.log(person.name); // Jhone 说明name不能被delete删除
console.log(person.sex); // underfind sex属性被删除
person.name = 'King';
console.log(person.name); //Jhone 说明name不能被被修改
for(proto in person){
console.log(proto)
}
// 返回的结果中 没有 name 属性
二、访问器属性
访问器属性不包含数据值,他们包含一对 getter 和setter, 不过这两个函数都不是必须的。在读取属性值时,会调用getter 函数,这个函数负责返回有效值;在写入属性值时,会调用seter函数并传入新值,这个函数负责决定如何处理数据。
- [[Configurable]]: 表示能否被 delete 删除,默认为 true
- [[Enumerable]]: 表示能否通过 for - in 循环返回属性, 默认为true
- [[Get]]: 在读取时属性是调用的函数,默认underfind
- [[Set]]: 在写入取时属性是调用的函数,默认underfind
例如:(还是上面的对象)
Object.defineProperty(person,"age",{
get:function(){
return this._age;
},
set:function(newVlaue){
if(newVlaue > 30){
this.height = 185;
}else{
this.height = 170;
}
}
})
测试结果:
console.log(person.height); //170 没有设置属性age(默认170)之前
people.age = 40;
console.log(person.height); // 185 设置age为40后(大于30) height也变化了
get 和 set 方法不是必须的,当你不设置get方法时,
console.log(people.age); // underfind
但你不设置 set 时,对应的属性是不能够被写入的。
三、定义多个属性
有时候我们想定义多个属性,ES5 为我们提供了 Object.defineProperties()
方法;
例如:
Object.defineProperties(person,{
_nameTwo:{
value:"LaoZhang"
},
nameTwo:{
get:function(){
return this._name;
},
set:function(newVlaue){
console.log(newVlaue)
}
},
sex:{
set:function(newVlaue){
console.log(newVlaue)
}
}
})
console.log(person.nameTwo) //LaoZhang
person.sex = "man" // man
注意: 属性用getter 去获取时,要将属性前加下划线 “_”这是js的常用的记号,表示只能通过对象方法访问。如果你没有加,那么 你用get 去获取属性时,浏览器可能会报错,但是你在外部访问时可以不用加, 如 console.log(person.nameTwo)
四、读取属性的特性
ES5为我们提供了一个Object.getOwnPropertyDescriptor()
方法来读取属性的特性
例如:
var descriptor =Object.getOwnPropertyDescriptor(person,"name");
console.log(descriptor.value) // Jhone
console.log(descriptor.configurable) //true 默认为true,如果你更改了configurable,这里会有变化
五、定义访问器的旧有方法
上面所讲的一些发方法,一般在IE9+ 能正常实现。要想在更早的IE版本实现要用非标准方法__defineGetter__
和 __defineSetter__
例如:
person.__defineGetter__("name",function(){
return this._name;
})
person.__defineSetter__("name",function(newValue){
console.log(newValue)
})