JS理解对象、对象的属性

理解对象

ECMA-262把对象定义为:”无序属性的集合,属性可以包含基本值、对象或者函数“,说的通俗一点,你的女朋友就是一个对象,性别、年龄是她的属性,逛街买衣服是她的方法。

1.创建自定义对象最简单的方式就是创建一个Object实例,然后为它添加属性和方法
JS理解对象、对象的属性_第1张图片

2.字面量创建的对象和上面new出来的实例一样,据有相同的属性和方法,这些属性
在创建的时候都带有一些特征的值,javascript通过这些特征值来定义他们的行为

JS理解对象、对象的属性_第2张图片

属性类型

ECMAScript中有两种属性值:数据属性和访问器属性

1.数据属性

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述行为的特性

[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者
能否把属性修改为访问器属性,默认值为true

[[Enumerable]]:表示能否通过for-in循环返回的属性。比如前面直接在对象上定义的属性。默认值
为true

[[Writable]]:表示能否修改属性的值。比如前面直接在对象上定义的属性,是可以修改他们的值的。默认值为true

[[Value]]:包含这个属性的数据值。默认值为undefined,读取值的时候从这个位置读;写入属性值的时候,把新的值保存在这个位置。

var person = {
name:“卢本伟”
}
在这个对象中,创建了一个名为name的属性,它的值是"卢本伟",其余的三个属性值默认为true。
如果你想要修改默认的特性,必须使用ES5中的 Object.defineProperty() 这个方法。这个方法接受三个参数:属性所在的对象属性的名字、和一个描述符对象,描述符对象的属性必须是ConfigurableEnumerableWritableValue 中的一个或者多个,可以修改对应的特征值,比如下面这段代码
JS理解对象、对象的属性_第3张图片
创建了一个name的属性,他的值是"卢本伟牛逼",设置了writable为false,代表这个属性是只读的,不能被修改,因此,即使后面修改值为”难受呀!马飞“,打印出来的name还是最初的值。如果在严格模式下,赋值操作将会导致抛出异常。类似的规则也适用与 [[Configurable]] (配置)属性
JS理解对象、对象的属性_第4张图片
Configurable配置为false,表示不能从对象中删除。如果在严格模式下,同样会导致报错。而且一但把属性定义为不可配置,就再也不能配置回来了,而且连调用Object.defineProperty() 修改除了writable以外的特性,都会导致错误
JS理解对象、对象的属性_第5张图片
在这里插入图片描述
简言之:可以调用Object.defineProperty() 方法修改同一个属性,但是把Configurable 特性设置为false了之后,它就不跟你玩了
在调用Object.defineProperty() 方法时,如果不指定,ConfigurableEnumerableWritable默认
为false,看清楚,这是调用Object.defineProperty() 方法的时候,不指定,才是默认为false。虽然大多数情况下你根本用不到这种方法,了解一下也是好的。

2.访问器属性

访问器不包含数据值,它们包含一堆getter和setter函数(不是必须的,可以省略),在读取访问器属性的值的时候,会调用getter函数,这个函数返回有效的值;写入的时候调用setter函数并传入新值。访问器属性同样也有4个特性,如下
[[Configurable]]:同上

[[Enumerable]]:同上

[[Get]]:在读取属性时调用的函数,默认值为undefined

[[Set]]:在设置属性时调用的函数,默认值为undefined
访问器属性不能像数据属性那样直接定义,必须通过Object.defineProperty() 来定义
JS理解对象、对象的属性_第6张图片
以上代码创建了一个book对象,并给它定义两个默认的属性: _year 和 edition。_year 前面的下划线是常用的记号,用于表示只能通过对象方法访问的属性(你就是要通过 对象 . _year来访问也不是不行)。而访问器属性year则包含一个getter函数数和一个setter函数。getter函数返回year的值, setter 函数通过计算来确定正确的版本。因此,把year属性修改为2005会导致year变成2005,而edition变为2。这是使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化。再提一点,复习一下前面的东西
JS理解对象、对象的属性_第7张图片
红色实线框里面的属性或者方法是不是颜色很浅?为什么?Object.defineProperty() 调用的时候,其余的属性不写的话默认是false, [[Enumerable]] 为false,表示该属性不能为for-in返回,所以颜色比较浅。你设置为true的话,year的颜色就变深了。
刚刚讲到哪里了?哦!对getter和setter,他们不一z定要同时指定,如果只制定getter意味着属性是只读的,如果在严格模式下写入会报错,同样只设置setter,读的话,只返回undefined
,严格模式下会报错。

3.定义多个属性

写一个对象的时候,可能会定义很多属性,那么ES5定一个同时设置多个属性的方法Object.defineProperties() 这个方法接受两个对象参数:第一个是要添加和修改其属性的对象,第二个对象的属性要和第一个对象中要添加或修改的属性一一对应。

JS理解对象、对象的属性_第8张图片
以上代码定义了两个数据属性(_year和edition)和一个访问器属性(year),与上一节定义的对象相同。只不过这里的属性是同一时间被创建的。

4.读取属性的特性

ES5中给出了Object.getOwnPropertyDescriptor() 方法,可以获取给定属性的描述符。这个方法接受两个参数:属性所在的对象,要读取其描述符的属性名称。返回值是一个对象
如果是访问器属性,这个对象的属性有configurable、enumerable、get和set
如果是数据属性,这个对象的属性有configurable、enumerable、writable和value

JS理解对象、对象的属性_第9张图片
对于数据属性_ year, value等于最初的值, configurable是false,而get等于undefined.
对于访问器属性year, value 等于undefined, enumerable 是false, 而get是-一个指向getter
函数的指针。

来源:《高级程序设计》(第3版)

你可能感兴趣的:(javascript)