Object.defineProperty熬夜整理的用法,保证你看的明白!

简介: Object.defineProperty熬夜整理的用法,保证你看的明白!

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>


1425695-20211102213306943-1849055354.png


使用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
相关文章
|
21天前
|
SQL Java 关系型数据库
MyBatis的动态SQL之OGNL(Object-Graph Navigation Language)表达式以及各种标签的用法
MyBatis的动态SQL之OGNL(Object-Graph Navigation Language)表达式以及各种标签的用法
22 0
|
21天前
|
前端开发 JavaScript 容器
你知道css中的object-fit的用法吗?
你知道css中的object-fit的用法吗?
57 0
|
9月前
|
Java
JAVA_Object 类的用法
JAVA_Object 类的用法
34 0
|
JavaScript 开发者
ES6之Object.assign()用法,Object.assign()到底是浅拷贝还是深拷贝?
ES6之Object.assign()用法,Object.assign()到底是浅拷贝还是深拷贝?
6431 1
ES6 Object.assign()的用法
ES6 Object.assign()的用法
86 0
成功解决AttributeError: 'BasicLSTMCell' object has no attribute '_kernel'+python下划线用法的几种常见用法理解
成功解决AttributeError: 'BasicLSTMCell' object has no attribute '_kernel'+python下划线用法的几种常见用法理解
Object C学习笔记21-typedef用法
  在上一章的学习过程中遇到了一个关键字typedef,这个关键字是C语言中的关键字,因为Object C是C的扩展同样也是支持typedef的。      一. 基本作用     typedef是C中的关键字,它的主要作用是给一个数据类型定义一个新的名称,这些类型报告内部数据类型,比如int,char 还有自定义类型struct,enum等。
968 0
Object C学习笔记22-#define 用法
  上一篇讲到了typedef 关键字的使用,可以参考文章 Object C 学习笔记--typedef用法 。而在c中还有另外一个很重要的关键字#define.   一. #define 简介     在C中利用预处理代码,可以让你的代码变得更加具有可读性,更加符合个人的编码风格,这也是C的强大之处。
1041 0