开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第36天,点击查看活动详情
属性描述符
在ES5之前,JavaScript语言本身并没有提供任何方法可以查看对象属性的特性,比如判断属性是否可修改。
思考如下代码:
var obj = {
a: 1
}
var obj2 = {}
obj2.b = 2
// {configurable: true,enumerable: true,value: 1,writable: true}
console.log(Object.getOwnPropertyDescriptor(obj, 'a'))
// {configurable: true,enumerable: true,value: 2,writable: true}
console.log(Object.getOwnPropertyDescriptor(obj2, 'b'))
这是我们最简单的定义对象属性的方法,默认的3个配置都是true。我们来简单看下这三个属性。
writable
表达的意思是是否可以修改属性的值。
思考如下代码:
var myObject = {}
Object.defineProperty(myObject, 'a', {
value: 100,
writable: false, // 不可写
configurable: true,
enumerable: true
})
myObject.a = 200
console.log(myObject.a) // 100
在给属性a定义属性描述符时设置可读写配置是false,再对该属性进行赋值,并没有改变这个属性值,说明不可写。
在严格模式下,会报错:
'use strict'
var myObject = {}
Object.defineProperty(myObject, 'a', {
value: 100,
writable: false, // 不可写
configurable: true,
enumerable: true
})
myObject.a = 200
console.log(myObject.a) // Uncaught TypeError: Cannot assign to read only property 'a'
报错了,因为严格模式下既然设置了属性不可写,再进行赋值,明显就违背了配置不可写原则。
configurable
如果configurable属性被设置为false,则不可通过defineProperty方法来设置属性。
var myObject = {
a: 1
}
Object.defineProperty(myObject, 'a', {
value: 2,
writable: true,
configurable: false, // 不可配置
enumerable: true
})
myObject.a = 3
console.log(myObject.a) // 3
// Uncaught TypeError: Cannot redefine property: a at Function.defineProperty
Object.defineProperty(myObject, 'a', {
value: 4,
writable: true,
configurable: true,
enumerable: true
})
console.log(myObject.a) // 未执行到
在上一个configurable设置为false之后,在通过defineProperty方法来配置属性则会产生报错,所设置的值也无效。
enumerable
这个属性描述符的含义是对象的属性是否可以被遍历到。
思考如下代码:
var myObject = {
a:1,
b:2,
c:3
}
for (let attr in myObject) {
// a b c
console.log(attr)
}
Object.defineProperty(myObject, 'b', {
value: 200,
writable: true,
configurable: true,
enumerable: false
})
for (let attr in myObject) {
// a c
console.log(attr)
}
console.log(myObject.b) // 200
第一次循环myObject对象的属性,都可以输出。然后设置属性b的enumerable描述符为false,再循环,则属性b不会被循环出来,但仍可以被访问到。