JavaScript对象之数据属性与访问器属性
栏目: JavaScript · 发布时间: 5年前
内容简介:首先介绍了创建1.1
首先介绍了 JavaScript
对象数据属性与访问器属性的相关概念,然后介绍了属性定义与读取的相关方法,最后对 JavaScript
对象数据属性与访问器属性的知识做了一些扩展。
一. 创建JavaScript对象
创建 JavaScript
对简单的方法有两种:一是直接创建一个 object
实例,然后为他添加属性与方法,二是通过对象字面量语法的方式创建。
1.1 new object
var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); }; 复制代码
上述实例创建了一个名为person的实例对象,并为其添加了三个属性( name
, age
, job
)和一个方法( sayName
)。
1.2 对象字面量
上述示例同样可通过对象字面量的语法实现如下。
var person = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function() { alert(this.name); } }; 复制代码
二. 属性类型
对于 1.1
与 1.2
的创建的每个实例都有自己的属性和方法,这些属性在创建时都带有一些特征值,这些特征值仅供内部使用,在 JavaScript
中不能直接访问他们,按规定这些特征值需要放在两对方括号中,例如 [[Enumerable]]
。
ECMAScript
中有两类属性,分别是 数据属性
与 选择器属性
1.1 数据属性
数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有 4 个描述其行为的 特性。
-
[[Configurable]]
:表示能否通过delete
删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。 -
[[Enumerable]]
:表示能否通过for-in循环返回属性。 -
[[Writable]]
:表示能否修改属性的值。 -
[[Value]]
:包含这个属性的数据值。
通过 new object
或者对象字面量方式创建对象定义的属性,他们的 [[Configurable]]
、 [[Enumerable]]
、 [[Writable]]
特征均为 true
,而 [[Value]]
值被设置为指定的值。
var person = { name: "Nicholas" } 复制代码
以上代码通过对象字面量的方式定义了一个 person
对象,并为它指定了 name
属性,此时 name
属性的四个特征值, [[Configurable]]
、 [[Enumerable]]
、 [[Writable]]
特征均为 true
,而 [[Value]]
为 Nicholas
。
要修改属性默认的特性,必须使用Object.defineProperty()方法,可同时修改一个或多个特性值,该方法接收三个参数:
-
object
:属性所在的对象 -
propertyName
:属性的名字 -
descripor
:属性的描述符,必须是[[Enumerable]]
、[[Writable]]
、[[Value]]
中的一个
var person = { name: fanweiren }; Object.defineProperty(person, "name", { writable: false, value: "Nicholas" }); alert(person.name); //"Nicholas" person.name = "Greg"; alert(person.name); //"Nicholas" 复制代码
以上代码将 name
属性的值设置为设置为 Nicholas
,并将 name
属性的 [[writable]]
特性值设为 false
,表示该属性只可读不可修改。如果尝试为它指定新值,非严格模式下,赋值操作会被忽略,在严格模式下,会抛出错误。
var person = { name: fanweiren }; Object.defineProperty(person, "name", { configurable: false, value: "Nicholas" }); alert(person.name); //"Nicholas" delete person.name; alert(person.name); //"Nicholas" 复制代码
把 [[Configurable]]
特性设置为false后,属性 name
既不能从对象中删除,此时调用delete在非严格模式下什么也不会发生,在严格模式下会抛出错误。
一旦把 [[Configurable]]
特性设置为false即不可配置后,就不能在变回可配置了。且设置为false后, [[Enumerable]]
、 [[Writable]]
也都不能修改了。
发现一个奇怪的现象, [[Configurable]]
特性设置为 false
后,如果 [[Writable]]
以前为 true
,则还可以将其修改为 false
,如果 [[Writable]]
以前为 false
,则不可修改。
1.2 访问器属性
访问器属性不包含数据值;它们包含一对儿 getter
和 setter
函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调用 getter
函数,这个函数负责返回有效的值;在写入访问器属性时,会调用 setter
函数并传入新值,这个函数负责决定如何处理数据。访问器属性有如下 4 个特性。
[[Configurable]] [[Enumerable]] [[Get]] [[Set]]
访问器属性不能直接定义,必须使用 Object.defineProperty()
来定义。请看下面的例子。
var book = { hideYear: 2004, edition: 1 }; Object.defineProperty(book, "year", { get: function(){ return this.hideYear; }, set: function(newValue){ if (newValue > 2004) { this.hideYear = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2 复制代码
以上代码定义了 hideYear
与 edition
两个数据属性,同时定义了 year
这个访问器属性。 year
访问器属性包含 get
与 set
两个方法, get
方法返回 hideYear
属性的值, set
方法通过计算来确定正确的版本。
三点总结:
-
所有直接通过
new object
或者对象字面量为对象添加的属性均为数据属性,访问器属性必须用Object.defineProperty()
定义。 -
通过
new object
或者对象字面量为对象添加的属性,其[[Configurable]]
、[[Enumerable]]
、[[Writable]]
属性默认均为true
,通过Object.defineProperty()
定义的属性,对于defineProperty
方法没定义的特征,默认为false
。
// 通过`new object`或者对象字面量为对象添加的属性 var person = { name: 'fanweiren' } // configurable、enumerable、writable均为true // 通过`Object.defineProperty()`定义的属性 Object.defineProperty(book, "name", { value: 'fanweiren' } // configurable、enumerable、writable均为false Object.defineProperty(book, "name", { configurable: true value: 'fanweiren' }// configurable为true,enumerable、writable为false 复制代码
vue
三. 定义多个属性
利用 Object.defineProperty()
定义单个属性。利用 Object.defineProperties()
同时定义多个属性,该方法接收两个参数,具体使用方式见如下代码。
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; } } } }); 复制代码
以上代码为对象 book
定义了三个属性,其中 _year
与 edition
为数据属性, year
为访问器属性。
四. 读取数据的属性
Object.getOwnPropertyDescriptor()
方法可以取得给定属性的描述符。这个方法返回值是一个对象,如果是访问器属性,这个对象的属性有 configurable
、 enumerable
、 get
和 set
;如果是数据属性,这
个对象的属性有 configurable
、 enumerable
、 writable
和 value
。对于第三部分(定义多个属性)的代码,调用 Object.getOwnPropertyDescriptor()
方法后结果如下:
var descriptor = Object.getOwnPropertyDescriptor(book, "_year"); console.log(JSON.stringify(descriptor)) //{"value":2004,"writable":false,"enumerable":false,"configurable":false} alert(typeof descriptor.get); //"undefined" var descriptor = Object.getOwnPropertyDescriptor(book, "year"); console.log(JSON.stringify(descriptor)) // {"enumerable":false,"configurable":false} alert(typeof descriptor.get); // function alert(typeof descriptor.set); // function 复制代码
五. 总结
本文从对象的创建引出对象数据属性与访问器属性的概念,首先介绍了数据属性与访问器属性的相关知识,然后介绍了属性定义与读取的相关方法。主要结论如下:
-
javascript
对象的属性分为数据属性与访问器属性两类,通过new object
与对象字面量定义的属性都为数据属性,访问器属性必须通过Object.defineProperty()
方法定义。 -
通过
new object
或者对象字面量为对象添加的属性,其[[Configurable]]
、[[Enumerable]]
、[[Writable]]
属性默认均为true
,通过Object.defineProperty()
定义的属性,对于defineProperty
方法没定义的特征,默认为false
。 - 一个属性要么为数据属性,要么为访问器属性,不可能既是数据属性又是访问器属性。
- 访问器属性使用的常见方式,即设置一个值会导致其他属性发生变化,该思想是vue双向绑定数据实现的核心内涵。
-
[[Configurable]]
表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,[[Enumerable]]
表示能否通过for-in
循环返回属性。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- python – Django属性错误. ‘module’对象没有属性’rindex’
- JavaScript之对象属性
- [译] 深入 JS 对象属性
- Python对象属性的那些事
- 什么是面向对象-类的属性
- 数组对象根据对象中指定的属性去重?你知道多少
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。