1

对象管理器(defineProperty)

在 JavaScript 里面声明一个变量,通常我们有三种方式可以实现:

 let person = {} // 对象字面量 let cat = new Object() // new 运算符 let dog = Object.create(null) // create 函数

我们可以简单的将 key 值和 value 值赋进去,但在 ES5 中 JavaScript 提供了一个对象管理器的方法给我们,让我们可以很精细的对每一个属性定制它们的行为,我们分别可以为属性设置:

  • 可配置特性(configurable)

  • 可枚举属性(enumerable)

  • 可以写特性(writable)

  • 值(value)

  • 设置 getter 方法(get)

  • 设置 setter 方法(set)

首先让我们看看如何使用Object.defineProperty来定制属性吧:

 let person = {} Object.defineProperty(person, 'name', { configurable: true, enumerable: true, writeable: true, value: '_我已经从中二毕业了' }) Object.defineProperty(person, 'age', { configurable: true, enumerable: true, writeable: true, value: 18 }) console.log(person.name) // _我已经从中二毕业了 console.log(person.age) // 18

通过上面的代码可以看出 Object.defineProperty 这个函数能够接受三个参数:

  1. obj:需要定义属性的对象

  2. prop:需被定义或修改的属性名

  3. descriptor:需被定义或修改的属性的描述符

语法

Object.defineProperty(obj, prop, descriptor)

可配置特性(configurable)

当 configurable 这个属性为 true 的时候表示这个属性可以从父对象中删除。当 configurable 设置为 false 的时候就会锁定这个属性,无法被修改。通过设置 configurable 我们可以将一些属性锁定,来防止别人的修改,这是一种防御编程形式,就像语言的内置对象一样(不过 JavaScript 的内置对象都可以被随意更改)。

 let person = {} Object.defineProperty(person, 'name', { configurable: false, value: '_我已经从中二毕业了' }) Object.defineProperty(person, 'age', { configurable: true, value: 18 }) delete person.name console.log(person.name) // _我已经从中二毕业了 delete person.age console.log(person.age) // undefined person.name = 'John' console.log(person.name) // _我已经从中二毕业了 person.age = 19 console.log(person.age) // 19

可枚举属性(enumerable)

一般来说我们会通过for in操作来遍历可以枚举的属性。当然我们也可以设置属性为不可枚举,这些属性就不能够被枚举了,从而防止遍历查找到这个属性。可以使用 propertyIsEnumerable 来判断某一个属性是否可以枚举。

 let person = {} Object.defineProperty(person, 'name', { enumerable: true, value: '_我已经从中二毕业了' }) Object.defineProperty(person, 'age', { enumerable: false, value: 18 }) // 只输出了 name for (var key in person) { console.log(key) } console.log(Object.keys(person)) // ["name"] console.log(Object.getOwnPropertyNames(person)) // ["name", "age"] console.log(person.propertyIsEnumerable('name')) // true console.log(person.propertyIsEnumerable('age')) // false console.log(person.age) // 18

可以写特性(writable)

当 writable 为 true 的时候,与属性相关联的值是可以更改的。否则,值就不能改变。

 let person = {} let person2 = person Object.defineProperty(person, 'name', { writable: false, value: '_我已经从中二毕业了' }) Object.defineProperty(person, 'age', { writable: true, value: 18 }) person.name = 'John' console.log(person.name) // _我已经从中二毕业了 console.log(person2.name) // _我已经从中二毕业了 person.age = 19 console.log(person.age) // 19 console.log(person.age) // 19 person2.name = 'John' console.log(person.name) // _我已经从中二毕业了 console.log(person2.name) // _我已经从中二毕业了 person2.age = 20 console.log(person.age) // 20 console.log(person.age) // 20

相关链接


_我已经从中二毕业了
7.9k 声望235 粉丝

不搞前端会死星人。