特别声明:如果您喜欢小站的内容,可以点击申请会员进行全站阅读。如果您对付费阅读有任何建议或想法,欢迎发送邮件至: airenliao@gmail.com!或添加QQ:874472854(^_^)
前段时间在学习Vue的双向绑定原理及实现时,简单的知道Object.defineProperty()
有很大的用处。这个方法会直接在一个对象上定义一个新属性,或者修改一个对象现有的属性,并返回这个对象。感觉他非常强大,但并不知道其中原委。回过头来重新补一下这方面的基础知识。
对象定义属性和赋值
在对象中,我们有很多种方式给其定义属性和赋值。最常见的是obj.prop = value
和obj['prop'] = value
。比如:
let Person = {}
Person.name = '大漠'
Person['age'] = 35
console.log(Person)
除了上述的方式之外,还可以使用Object.defineProperty()
方法来定义和修改对象属性。下面我们就来好好的探讨一下这个方法。
Object.defineProperty()语法
Object.defineProperty()
的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性,并返回这个对象,我们先来看一下怎么使用这个方法:
Object.defineProperty(obj, prop, descriptor)
这个方法有三个参数:
obj
:需要被定义(或修改)属性的那个对象prop
:需要被定义(或修改)的属性名descriptor
:定义(或修改)的属性prop
的描述
其返回值是被传递给函数的对象。
该方法允许精确添加或修改对象的属性。一般情况下,为对象添加属性是通过赋值来创建并显示在属性枚举中(for...in
或Object.keys
方法),但这种方式添加的属性值可以被改变,也可以被删除。而使用Object.defineProperty()
则允许改变这些额外细节的默认设置。例如,默认情况下,使用Object.defineProperty()
增加的属性值是不可改变的。
属性特性和内部属性
JavaScript中有三种类型的属性:
- 命名数据属性:拥有一个确定的值的属性。这也是最常见的属性
- 命名访问器属性:通过
getter
和setter
进行读取和赋值的属性 - 内部属性:由JavaScript引擎内部使用的属性,不能通过JavaScript代码直接访问到,不过可以通过一些方法间接的读取和设置。比如,每个对象都有一个内部属性
[[Prototype]]
,你不能直接访问这个属性,但可以通过Object.getPrototypeOf()
方法间接的读取到它的值。虽然内部属性通常用一个双吕括号包围的名称来表示,但实际上这并不是它们的名字,它们是一种抽象操作,是不可见的,根本没有上面两种属性有的那种字符串类型的属性名
属性特性
对象中每个属性都有四个特性。两种类型的属性一共有六个属性特性:
- 命名数据属性特有的特性:属性的值的
[[Value]]
特性和控制属性的值是否可以修改的[[Writable]]
特性 - 命名访问器属性特有的特性:存储着
getter
方法的[[Get]]
和存储着setter
方法的[[Set]]
- 两种属性都有的特性:如果一个属性是不可枚举的,则一些操作下,这个属性是不可见的,比如
for...in
和Object.keys
,那么可以通过[[Enumerable]]
特性来设置;如果一个属性是不可配置的,则该属性的所有特性([[Value]]
)都不可改变,那么可以通过[[Configurable]]
特性来设置
内部属性
除了上面所说的之外,下面几个是所有对象都有的内部属性:
[[Prototype]]
:对象的原型[[Extensible]]
:对象是否可扩展,也就是是否可以添加新的属性[[DefineOwnProperty]]
:定义一个属性的内部方法[[Put]]
:为一个属性赋值的内部方法
属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。
- 数据描述符:是一个拥有可写或不可写值的属性
- 存取描述符:是由一对
getter
、setter
函数功能来描述的属性
描述符必须是两种形式之一;不能同时是两者。另外,属性描述符可以将一个属性的所有特性编码成一个对象并返回。例如:
Object.defineProperty(obj, 'key', {
enumerable: false,
configurable: false,
writable: false,
value: 'static'
})
属性描述符除了在Object.defineProperty()
中使用之外,还常常使用在Object.getOwnPropertyDescriptor()
和Object.create()
中。如果对象中的某个属性省略了属性描述符,则该属性会取一个默认值:
属性名 | 默认值 |
---|---|
value |
undefined |
get |
undefined |
set |
undefined |
writable |
false |
enumerable |
false |
configurable |
false |
先对属性描述符做一个简单的归纳,因为后面接下来的篇幅都将围绕着Object.defineProperty()
的属性描述符descriptor
来展开的。
数据描述符和存取描述均具有以下可选键值:
configurable
:这个特性决定了对象的属性是否可以被删除,以及除writable
特性外的其它特性是否可以被修改;并且writable
特性值只可以是false
。默认为false
。同样通过示例来帮助我们理解这个描述符的特性:
如需转载,烦请注明出处:https://www.w3cplus.com/javascript/object-defineproperty.html
如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!