第六章 面向对象的程序设计 数据属性+访问器属性
6.1 理解对象
1:属性类型(数据属性+访问器属性)
①数据属性:
[[Configurable]]是否可以删除属性
[[Enumerable]]是否可以通过for-in循环返回属性
[[Writable]]是否可以修改属性
[[Value]]属性的数据值
var person = { }; Object.defineProperty(person,"name",{ writable:false, value: "wang" }); alert(person.name); //wang
②访问器属性
[[Configurable]]是否可以删除属性
[[Enumerable]]是否可以通过for-in循环返回属性
[[Get]]读取属性时调用的函数
[[Set]]写入属性时调用的函数
var person = { name: "2005" }; Object.defineProperty(person,"name",{ get: function(){ return this.name; }, set: function(newValue){ this._year = newValue; this.edition += newValue - 2004; } }); alert(person.name);
上面这种写法会出现Uncaught RangeError: Maximum call stack size exceeded这种报错,之所以会报错,是因为不断的get会继续触发get,进入死循环,导致内存溢出!
var person = { _name: "2005" }; Object.defineProperty(person,"name",{ get: function(){ return this._name; }, set: function(newValue){ this._year = newValue; this.edition += newValue - 2004; } }); alert(person.name);
这种写法将有的name写成_name可以正确访问到
【注】访问器属性和数据属性的后两个属性如果同时写在一个defineProperty函数中的话,会报错。需要分开写。
2:定义多个属性
Object.defineProperties(x,y) x接收对象,y的属性与第一个对象中要添加或修改的属性一一对应
var book = {}; Object.defineProperties(books,{ _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; } } } });
3:读取多个属性
var book = {}; Object.defineProperties(books,{ _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; } } } }); var descriptor = Object.getOwnPropertyDescriptor(book,"_year"); //数据属性对象,可以访问数据属性的四个属性 var descriptor = Object.getOwnPropertyDescriptor(book,"year"); //访问器属性对象,可以访问访问器属性的四个属性
【注】_year前面的下划线是一种常用记号,用于表示只能通过对象方法访问的属性
cncncn