js中对象属性的类型和属性的特性(属性描述符)

ES5中对象的属性可以分为数据属性和访问器属性

  1. 数据属性
    数据属性包含以下4个特性:
    [[configurable]]:表示属性是否可以被delete,以及其他3个属性描述符的值是否可以被修改,甚至改写成访问器属性(Vue的ObServer就是这样进行数据劫持的)
    [[enumerable]]:是否可枚举,是否能通过for in 循环返回该属性
    [[writable]]: 是否可修改
    [[value]]:属性的数据值,默认是undefined
    数据属性可以通过字面量形式直接定义(包括obj.proper),或者通过Object.defineProperty(obj)来定义,如:
var obj = {
	_name: 'zyp',
	_age: 18,
}
Object.defineProperty(obj, 'like', {
	value: 'sleep'
})

用Object.getOwnPropertyDescriptors(obj)可以获取对象的所有属性,包括属性的特性。

var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

输出的结果见下图,我们可以看到:通过字面量直接定义的数据属性的[[configurable]]、[[enumerable]]、[[value]]三个特性值均默认为true;通过defineProperty()定义的数据属性的[[configurable]]、[[enumerable]]、[[value]]三个特性值均默认为false。
在这里插入图片描述
2. 访问器属性(ie9+支持
访问器属性包含以下4个特性:

[[configurable]]:表示属性是否可以被delete,以及其他3个属性描述符的值是否可以被修改,甚至改写成数据属性。
[[enumerable]]:是否可枚举,是否能通过for in 循环返回该属性
[[set]]:设置属性值是访问的函数。默认是undefined
[[get]]:读取属性值是访问的函数。默认是undefined
访问器属性只能通过Object.defineProperty(obj)来进行定义,如:

Object.defineProperty(obj, 'name', {
	get: function() {
		return this._name
	},
	set: function(newVal) {
		this._name = newVal
	}
})
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

同样,通过defineProperty()函数定义的访问器属性的[[configurable]]、[[enumerable]]两个特性值均默认为false,如图:
在这里插入图片描述

如果只定义了set特性或者只定义了get特性

Object.defineProperty(obj, 'age', {
	set: function(newVal) {
		this._age = newVal
	}
})
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)
var age = obj.age //得到的age值为undefined

因此,在非严格模式下,如果只定义了set特性,那么获取得到该访问器属性的值为undefined, 严格模式下会报错(高程上是这么说的,但是实际在chrome控制台中用’use strict’并没有抛出错误)。

接下来对数据属性和访问器属性共有的configurable特性进行研究:
针对obj中的数据属性_age和_name

  • _age属性的configurable特性值为true,我们可以对其enumerable、writable、 value三个特性进行修改。
Object.defineProperty(obj, '_age', {
	enumerable: false,
	writable: false,
	value: 19
})
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

在这里插入图片描述
也可以将其修改为访问器属性,或者直接delete该属性,这里只演示delete操作。

delete obj._age
var propers = Object.getOwnPropertyDescriptors(obj)
console.log('propers', propers)

在这里插入图片描述

  • 我们将_name的configurable属性为false后,我们只能将writable特性修改为false,不能修改其他特性,否则会报错。
Object.defineProperty(obj, '_name', {
   	configurable: false
})
Object.defineProperty(obj, '_name', {
   	writable: false
})   //不报错
Object.defineProperty(obj, '_name', {
   	value: 'zyp1'
})   

在这里插入图片描述
也不能进行delete操作(无效)。

delete obj._name

在这里插入图片描述

注意:数据属性的特性和访问器属性的特性不能同时存在于一个属性中。
参考:JavaScript高级程序设计(第3版) 6.1.1

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值