JavaScript高级程序设计第三版 139页 Object.defineProperty()函数:
Object.defineProperty()方法接收三个参数,属性所在的对象,属性的名字和一个描述符对象。其中描述符对象的属性必须是:configurable,writeable,enumerable,value。设置其中一个或多个值,可以修改对应的特性值。
JavaScript高级程序设计第三版 139页 数据属性:
数据属性包含一个数据值的位置。在这个位置可以读取和写入值
javascript
var person = { name : "Nicholas" } //第一个问题: //这里面的name属性是数据属性?
JavaScript高级程序设计第三版 141页,访问器属性:
访问器属性不包含数据值
javascript
var book = { _year : 2004,//_year前面下划线是常用的记号,表示只能通过对象方法访问的属性 edition : 1 }; Object.defineProperty(book,"year",{ get : function () { return this._year; }, set : function (newValue) { if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; //第二个问题:上行代码为什么没有给book新添加一个year属性? //第三个问题: //如果上行代码注释掉,alert(book.year)为undefined。不注释的话alert(book.year)警告框显示2005. 可是book中并没有添加一个year属性,为什么在执行上一行代码以后便可以alert了?弹出的值是_year的值,证明book.year访问的是_year了吧?_year不是只能通过对象方法访问么?为什么直接alert(book.year)便可以访问了?
name
是数据属性。书上说数据属性包含一个数据的位置。在这个位置可以读取和写入值。言下之意即,数据属性是可以直接通过对象.属性
的形式访问和赋值的。题中name
可以这样做。所以它是一个数据属性。通过
Object.defineProperty()
方法,可以创建数据属性(并设定其[[Enumerable]]等内部属性),也可以创建访问器属性(访问器属性仅包含getter
和setter
函数,当然这两个也不是必须的)。第二问中这样的创建方式即创建了book
对象的访问器属性,而非数据属性.year
(当然名字可以自定义,随便取)是book
对象一个访问器属性。直接调用book.year
,即调用了这个访问器属性中定义的get
方法,返回book._year
这个数据属性。如果给book.year
赋值,就是调用了这个访问器属性中定义的set
方法。楼主可以在get
和set
方法体中分别加入console.log("某个字符")
,这样的代码,再调用book.year
或给其赋值,应该就明白了。数据属性不仅可以直接访问,也可以通过定义的访问器来专门访问。P.S. 可以在浏览器的控制台中打印
book
对象,你会发现是这样的: