文章目录
1. 最常用的js对象是字面量形式的对象
例如:创建一个person对象。
var person = {
name: "xiaoming",
age: 29,
job: "Engineer",
sayName: function () {
alert(this.name);
}
};
js还要很多其他创建对象的方式,可以参考这篇文章JS面向对象
2. 对js对象的属性常用操作
- 取值:
person.name
或person['name']
- 赋值:
person.name = "xiaohong";
或person['name'] = "xiaohong"
- 删除属性:
delete person.name
- 遍历属性:
for-in
执行举例:以前面定义的那个person对象为例。
//取值
console.log(person.name);//xiaoming
console.log(person['name']);//xiaoming
//赋值
person.name = "xiaohong";
person['name'] = "xiaohong";
console.log(person.name);//xiaohong
//删除属性
delete person.name;
console.log(person.name);//undefined
//遍历属性
for(var key in person){
console.log(key + ":" + person[key]);
}
/**
* 遍历结果如下:
age:29
job:Engineer
sayName:function () {
alert(this.name);
}
*/
3. 定义属性Object.defineProperty()
js引擎允许对属性操作的控制,需要使用方法
Object.defineProperty()
来实现。这个方法接收三个参数:属性所在的对象、属性的名字、描述符对象。
3.1 描述符对象包含以下属性:
configurable
:表示能否通过 delete 删除属性从而重新设置属性,是否可以利用defineProperty方法重新定义属性(正常情况下是可以反复使用该方法重新设置属性的)。默认为true。enumerable
:表示能否通过 for-in 循环返回属性。默认为true。writable
:表示能否修改属性的值。默认值为 true。value
:属性值,读一个对象的属性值时先读的是这个值。默认值为 undefined。get
:读取属性值时调用的函数。默认值为 undefined。set
:给属性赋值时调用的函数。默认值为 undefined。
注意:
(writable、value)与(get、set)是不能同时使用的。
否则会报错。其实这一点也是符合逻辑的,因为get和set是用来读属性值和给属性赋值时操作属性的方法。如果这时设置writable为false,或者设置属性的value值,那get或set方法将变得没有意义。所以他们不能共存,也没必要共存。
JavaScript高级程序设计那本书上,将configurable、enumerable、writable、value这四种属性组合时叫做数据属性
,将configurable、enumerable、get、set这四种属性组合时叫做访问器属性
。
3.2 属性configurable和enumerable举例:
还是以最开始定义的那个person对象为例。将这两个值都设置为false
Object.defineProperty(person,"name",{
configurable : false,
enumerable : false
});
此时name属性无法被delete删除,无法用defineProperty方法重新定义。
Object.defineProperty(person,"name",{
configurable : false,
enumerable : false
});
delete person.name;//删除name属性值
console.log(person.name);//结果是xiaoming,并不是undefined
//利用defineProperty方法重新定义name属性
Object.defineProperty(person,"name",{
configurable : false,
get : function () {
return this.age;
}
});//浏览器直接报错:Uncaught TypeError: Cannot redefine property: name
执行结果如下:
name属性也无法用for-in枚举出来。
//迭代结果没有name属性
for(var key in person){
console.log(key + ":" + person[key]);
}
执行结果如下:name属性并没有被迭代出来。
3.3 属性writable和value举例:将name设置为不可重写,且设置其value值。
js在取值时优查找value的值,然后再去对象中设置的值。
Object.defineProperty(person,"name",{
writable: false,//设置name属性不能被改写
value: "ligang"//将name的属性值设置为ligang
});
person.name = "fangfang";//对name属性重新赋值
console.log(person.name);//结果为ligang,如果writable被设置为true,那么name属性值为fangfang
3.4 属性get和set举例:每当设置name属性时,再次取值时,将返回结果加上一些描述。
注意:如果对某个属性设置的get/set方法,那么这个属性在取值时会调用get方法,可能会出现容易被忽略的地方,例如get方法像下面例子中这样设置,在没有对name属性赋值之前就取值,name会失去最初字面量对象中设置的值。
Object.defineProperty(person,"name",{
set:function (v) {
this.temp = "我的名字是" + v;
},
get:function () {
return this.temp;
}
});
console.log(person.name);//执行结果是:undefined。因为此时取值调用get方法,返回的是那个没有被赋值过的this.temp
person.name = "mike";//赋值的时候执行set方法
var result = person.name;//读值的时候执行get方法
console.log(result);//执行结果是:我的名字是mike
4. 定义多个属性Object.defineProperties()
这个方法是Object.defineProperty()方法的加强版,可以一次性设置多个属性。举例:
var book = {};
Object.defineProperties(book, {
_year: {
value: 2004
},
edition: {
value: 1
},
year: {
get: function () {
return this._year;
},
set: function (newValue) {
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
});
5. 读取属性的描述对象Object.getOwnPropertyDescriptor()
以book对象为例:
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");//读取book的属性描述对象
console.log(descriptor);
备注:本文内容是学习“JavaScript高级程序设计”这本书整理的笔记。