赞
踩
我们经常使用的定义与赋值方法 obj.xxx = value 或 obj['xxx'] = value,并且可以定义任意类型的值,如下所示:
- let obj = {};
- obj.name = 'bjl';
- obj['age'] = 18;
- obj.sayHi = function() {console.log('Hi')};
- console.log(obj) // {name: 'bjl', age: 18, sayHi: fn}
Object.defineProperty() 的作用就是直接在一个对象上定义新属性,或者修改一个已经存在的属性。语法格式为:
Object.defineProperty(object, propName, descriptor);
都有哪些属性描述符呢?如下:
通过 Object.defineProperty() 为对象定义属性有两种形式,但不能混合使用,分别是数据描述符、存取描述符。
当使用了 value 和 writable 属性,不允许使用 getter 或 setter 这两个方法。
- let obj = {};
- Object.defineProperty(obj, 'name', {
- value: 'bjl'
- })
- console.log(obj.name) // bjl
- let obj = {};
- Object.defineProperty(obj, 'name', {
- value: 'bjl'
- })
- obj.name = 'bao';
- console.log(obj.name) // bjl
- let obj = {};
- Object.defineProperty(obj, 'name', {
- value: 'bjl',
- writable: true // 表示可以进行修改
- })
- obj.name = 'bao';
- console.log(obj.name) // bao
- let obj = {
- name: 'bjl'
- };
- Object.defineProperty(obj, 'name', {
- writable: false //手动设置name属性不可被修改
- })
- obj.name = 'bao';
- console.log(obj.name) // bjl
当声明一个对象时,它里面的属性的内部属性的默认值都为 true,也就是说 writable 这时的默认值为 true,这就是为什么上面的 name 如果不想被修改就需要手动去设置 writable 属性的原因。我们可以使用 Object.getOwnPropertyDescriptors() 去检测属性的内部属性的具体描述,如下:
- let obj = {
- name: 'bjl'
- }
- console.log(Object.getOwnPropertyDescriptors(obj))
-
- Object.defineProperty(obj, 'age', {
- value: 18
- })
- console.log(Object.getOwnPropertyDescriptors(obj))
打印如下:
当使用 get 或 set 方法,不允许使用 value 和 writable 这两个属性。
- let obj = {};
- let temp = 'bjl';
- Object.defineProperty(obj, 'name', {
- get: function() {
- return temp
- },
- set: function(val) {
- temp = val
- }
- })
- console.log(obj.name) // bjl
- // 当修改属性时,就会触发方法里的set方法
- obj.name = 'bao';
- console.log(obj.name) // bao
有时我们会对对象进行遍历,只有被枚举的属性可以被遍历到,如下所示:
- let obj = {
- name: 'bjl',
- age: 18
- }
- Object.defineProperty(obj, 'sex', {
- value: '女'
- })
- for(let key in obj) {
- console.log(key) // name age
- }
- let obj = {
- name: 'bjl',
- age: 18
- }
- Object.defineProperty(obj, 'sex', {
- value: '女'
- })
- console.log(Object.keys(obj)) // ['name', 'age']
- Object.keys(obj).map(key => {
- console.log(key) // name age
- })
我们可以看出,使用 Object.defineProperty() 添加的属性不能被枚举到,也就是不能被遍历到。Object.keys() 返回的是可以被枚举到的数组,所以打印结果如上所述。
添加 enumerable 描述属性可以改变,如下所示:
- let obj = {
- name: 'bjl',
- age: 18
- }
- Object.defineProperty(obj, 'sex', {
- value: '女',
- enumerable: true
- })
- console.log(Object.keys(obj)) // ['name', 'age', 'sex']
- Object.keys(obj).map(key => {
- console.log(key) // name age sex
- })
- let obj = {
- name: 'bjl',
- age: 18
- }
- delete obj.name;
- console.log(obj) // {age: 18}
- let obj = {
- name: 'bjl',
- age: 18
- }
- Object.defineProperty(obj, 'sex', {
- value: '女'
- })
- delete obj.sex;
- console.log(obj) // {name: 'bjl', age: 18, sex: '女'}
- let obj = {
- name: 'bjl',
- age: 18
- }
- Object.defineProperty(obj, 'sex', {
- value: '女',
- configurable: true
- })
- Object.defineProperty(obj, 'name', {
- configurable: true
- })
- delete obj.sex;
- delete obj.name;
- console.log(obj) // {age: 18}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。