JavaScript理解对象:属性类型


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)便可以访问了?

javascript属性类型 javascript对象 JavaScript

rosette 10 years, 10 months ago

第一个问题:是数据属性。
第二个问题:book.year = 2005; Object.defineProperty给book的_year属性新建一个名字year。
第三个问题:_year : 2004;表示book就有一个_year属性,js本身没有访问控制功能,你可以试试alert(book._year)一样可以访问

真鼻毛爆爆拳 answered 10 years, 10 months ago

楼上已经说的很明了了,我在补充一点。
javascript 一共用三种属性

普通属性 (也就是楼主说的数据属性), 这种属性是用户赋给它们,它们就返回什么,不会做额外的事情
var person = { name : "Nicholas" } alert(person.name) // "Nicholas"

内部属性 ,比如数组的 length 属性,函数的 prototype 属性, DOM 节点的 innerHTML 属性,用户对它们进行赋值后, 再取值时,它不一定按我们的预期做事,此外还会做一些格外的事情。另外,我们也很难改变它们的行为。 比如说某一数组,它的长度为10, 当我们设置它为11时,它就会增加一个 undefined 元素,再设置为9时,就会从后面删掉两个元素。 函数的 prototype 如果被改变,相当于将其父类改变了,会 new 不同类型的实例。 DOM innerHTML ,我们赋值时是一个字符串,再取出时,这字符串可能会与原来的不一样, 并且在原元素上生成了不一样的子节点。

访问器属性 ,允许用户在赋值或取值都经过预先设定的函数,从而实现内部属性的那一种特殊效果。

狂放不羁爱奶妈 answered 10 years, 10 months ago

  1. name 是数据属性。书上说 数据属性包含一个数据的位置。在这个位置可以读取和写入值 。言下之意即,数据属性是可以直接通过 对象.属性 的形式访问和赋值的。题中 name 可以这样做。所以它是一个数据属性。

  2. 通过 Object.defineProperty() 方法,可以创建数据属性(并设定其[[Enumerable]]等内部属性),也可以创建访问器属性(访问器属性仅包含 getter setter 函数,当然这两个也不是必须的)。第二问中这样的创建方式即创建了 book 对象的访问器属性,而非数据属性.

  3. 接第二点, year (当然名字可以自定义,随便取)是 book 对象一个访问器属性。直接调用 book.year ,即调用了这个访问器属性中定义的 get 方法,返回 book._year 这个数据属性。如果给 book.year 赋值,就是调用了这个访问器属性中定义的 set 方法。楼主可以在 get set 方法体中分别加入 console.log("某个字符") ,这样的代码,再调用 book.year 或给其赋值,应该就明白了。数据属性不仅可以直接访问,也可以通过定义的访问器来专门访问。
    P.S. 可以在浏览器的控制台中打印 book 对象,你会发现是这样的:
    图片描述
最是一抹蘇打綠 answered 10 years, 10 months ago

Your Answer