Object.defineProperty的基本使用
<script> let personObj={ name:'何西亚', sex:'男' } //我们想给这个对象添加一个属性 // 第一个参数是你要添加的对象名, // 第二个参数你要添加的key值 // 第三个参数是 一个配置项 是个对象 Object.defineProperty(personObj,'age',{ value:35 }) //输出 {name: "何西亚", sex: "男", age: 35} console.log( personObj); </script>
为啥要使用 Object.defineProperty 添加key值
有的同学可能会说,我使用通过点和[]的方式难道不好吗
<script> let personObj={ name:'何西亚', sex:'男' } personObj['age']=35 personObj.height=1.86 //使用这一种方式也可以添加key值,难道这样不香吗 console.log(personObj); </script>
这样是可以的,但是我使用 Object.defineProperty
是非常高级的
那么高级在哪里呢?
咳咳咳,使用 Object.defineProperty添加的key值,
是不会参与枚举
枚举:简单点说就是不会参与循环。[这样描述可能不太准确]
我们可以证明一下:Object.defineProperty添加的key值不会被遍历
Object.defineProperty添加的key值不会被遍历
<script> let personObj={ name:'何西亚', sex:'男' } Object.defineProperty(personObj,'age',{ value:35 }) // Object.keys()返回对象键名key组成的数组 console.log(Object.keys(personObj)); // [name,sex ] //在这里我们发现age这个属性没有返回 //所以说明了【Object.defineProperty添加的key值不会被遍历】 </script>
想要 Object.defineProperty添加的key值被遍历
有的同学喜欢去钻牛角尖,说我非要去让它遍历。
也不是不可以,我们之前说过 Object.defineProperty
第三个参数是 一个配置项 是个对象
这样配置enumerable:true 表示可以枚举
let personObj={ name:'何西亚', sex:'男' } // Object.defineProperty(personObj,'age',{ value:35, enumerable:true }) // Object.keys()返回对象键名key组成的数组 console.log(Object.keys(personObj)); // [name,sex,age ] //这个时候我们发现是可以枚举了
Object.defineProperty中key值是否可以被修改
<script> let personObj={ name:'何西亚', sex:'男' } Object.defineProperty(personObj,'age',{ value:35, enumerable:true }) personObj.age='350' // 通过这样的方式,是不可以被修改的哈 console.log(personObj.age); //输出 35 </script> 如果我们想要age可以被修改,我们配置 let personObj={ name:'何西亚', sex:'男' } //配置 enumerable:true, Object.defineProperty(personObj,'age',{ value:35, enumerable:true,writable:true }) personObj.age='350' // 这样就可以修改年龄了 console.log(personObj.age); //输出 350
Object.defineProperty中新增的key值可以被删除
let personObj={ name:'何西亚', sex:'男' } // configurable:true 表示后面可以删除age这个属性, // 正常情况下age是不可以被删除的哦! Object.defineProperty(personObj,'age',{ value:35, configurable:true }) delete personObj.age console.log(personObj) 输出 { name:'何西亚', sex:'男'}
需求描述
我们想这样操作:
一个对象中的某一个属性值去读取某一个变量
当这个变量的值发生变化后,对象中的那个属性值发生变化
let num=35 let personObj={ name:'何西亚', sex:'男', age:num } //输出35 console.log('修改前', personObj.age ) num=36 //修改后仍然输出35,但是我想让它输出36 console.log('修改后',personObj.age );
Object.defineProperty的get函数的使用
这个时候,Object.defineProperty的get函数的来帮助我们了!
<script> let num=35 let personObj={ name:'何西亚', sex:'男', age:num } num=36 Object.defineProperty(personObj,'age',{ //当有人读取 personObj的age属性的时候 // 就会触发get函数【getter】,该函数就会被调用 // 函数的返回值就是age的值 get:function(){ console.log('读取age属性的时候回触发该函数') return num } }) console.log('修改后',personObj.age ); //输出36 </script>
使用Object.defineProperty的set函数的原因
<script> let num = 35 let personObj = { name: '何西亚', sex: '男', age: num } num = 36 //可以修改age的值 Object.defineProperty(personObj, 'age', { //当有人读取 personObj的age属性的时候 // 就会触发get函数【getter】,该函数就会被调用 // 函数的返回值就是age的值 get: function () { console.log('读取age属性的时候回触发该函数') return num } }) //后面通过这样的方式修改age的值会失败 personObj.age='350' //本来我们期待是350,但是实际上是 36 console.log('修改后', personObj.age); 这个时候我们就需要使用set函数了,它就可以解决这个问题 </script>
Object.defineProperty中set函数的使用
<script> let num=35 let personObj={ name:'何西亚', sex:'男', age:num } num=36 Object.defineProperty(personObj,'age',{ //当有人读取 personObj的age属性的时候 // 就会触发get函数【getter】,该函数就会被调用 // 函数的返回值就是age的值 get:function(){ console.log('读取age属性的时候回触发该函数') return num }, // 当有人修改age属性的时候,set函数【setter】就会被触发 // 且会收到修改的具体值 set:function(value){ console.log('修改age了',value) // 修改后需要进行赋值,否者通过personObj.age='350'修改会失败 num=value } }) personObj.age='350' console.log('修改后',personObj.age ); //输出350