Object.defineProperty()个人理解

Object.defineProperty()用于定义对象中属性的特性,这些特性属于对象内部值,因此在JS中不能直接访问它们。

在ES5中,有两种属性,包括数据属性和访问器属性

数据属性

数据属性包含一个数据值的位置,在这个位置可以读取和写入值,数据属性有4个用于描述其行为的特性

  • [[ Configurable ]] 表示能否delete删除属性,能否修改属性的特性,能否将属性改为访问器属性,直接在对象上定义属性时,默认值为true
  • [[ Enumerable ]] 能否通过循环返回该属性。直接在对象上定义的属性,该特性默认为true
  • [[ Writing ]] 能否修改属性的值。直接在对象上定义的属性,该特性默认值为true
  • [[ Value ]] 该属性的数据值。读取属性值时,从这个位置读,写入新属性时,将新值保存在这个位置。 默认值为undefined

使用Object.defineProperty() 修改属性的默认特性,接受三个参数: 属性所在的对象, 属性名 ,以及一个描述符对象 描述符对象的属性必须是上述四个特性,不能有别的属性。设置其中的一个或多个值,就可以修改对应的特性值

例:

let obj = {name: "lalala",age: 15,idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {writable: false,    //不可被修改enumerable: false,   //不可被遍历value: "Well"
})console.log(obj.name)    //Well
obj.name = 'Nigo'   //严格模式下会报错,非严格模式没事
console.log(obj.name)  //WellObject.keys(obj).forEach(key => {console.log(key);   //age , idol   不包含name属性
})

可以多次调用object.defineProperty()方法去修改同一个属性,但是如果第一次修改将configurable设为false,就不能再次修改了,会报错

let obj = {name: "lalala",age: 15,idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {   //没有设置configurable:false是可以再次修改的writable: false,    //不可被修改enumerable: false,   //不可被遍历value: "Well"
})console.log(obj.name)    //Well
obj.name = 'Nigo'   //严格模式下会报错,非严格模式没事
console.log(obj.name)  //WellObject.keys(obj).forEach(key => {console.log(key);   //age , idol   不包含name属性
})Object.defineProperty(obj , 'name' , {writable: true,    //该为trueenumerable: false,   //不可被遍历value: "Well"
})obj.name = 'Nigo'   //可以修改属性了
console.log(obj.name)  //Nigo
let obj = {name: "lalala",age: 15,idol: 'CR7'
};
Object.defineProperty(obj , 'name' , {   //没有设置configurable:false是可以再次修改的configurable:false,   //不可再次修改该属性的特性writable: false,    //不可被修改enumerable: false,   //不可被遍历value: "Well"
})console.log(obj.name)    //Well
obj.name = 'Nigo'   //严格模式下会报错,非严格模式没事
console.log(obj.name)  //WellObject.keys(obj).forEach(key => {console.log(key);   //age , idol   不包含name属性
})Object.defineProperty(obj , 'name' , {   //这里直接报错writable: true,    enumerable: false,   value: "Well"
})

访问器属性

访问器属性不包含数据值,包含一对儿getter和setter函数(不是必须的)

另外,当一个属性设置了get 和 set 方法,它就是一个访问器属性

getter函数

读取访问器属性时调用的函数

setter函数

写入访问器属性时,调用setter函数,并传入新值,setter函数决定如何处理数据

访问器属性不能直接定义,同样必须通过Object.defineProperty()来定义

        const obj = {name: 'Well',_age: 22,  //表示只有通过对象方法能访问到的属性}Object.defineProperty(obj , 'age' , {configurable:true,   //表示能否delete删除属性,能否修改属性的特性,能否将属性改为数据属性,默认falseenumerable: true,  //能否被遍历到,默认falseget() {console.log("获取age的值");return this._age;},set(newV) {console.log("写入新值");this._age = newV;  //可以通过setter函数改变对象中的其他属性值}});obj.age = 24;  //写入新值console.log(obj.age); //获取age的值    24obj.age = 26;  //写入新值console.log(obj.age);  //获取age的值   26console.log(obj._age) //26

访问器属性名不可与对象原有属性名重名,否则死循环导致栈溢出

监视对象中数据的变化:

 const obj = {a: 1,b: 2,c: 3}Object.keys(obj).forEach(key=>{let value = obj[key]Object.defineProperty(obj,key,{get(){console.log(`获取${key}的行为被我劫持了`)return value},set(v){console.log(`${key}的改变被我劫持了`);value = v;}})})console.log(obj.b);  //获取b的行为被我劫持了  2obj.c = 5;  //c的改变被我劫持了

不是一定要同时定义getter和setter

​ 只定义setter意味着只能写入,不能读,读没有getter的属性时,严格模式报错,非严格模式返回undefined

​ 只定义getter意味着只能读,不能写入,尝试写入,严格模式下报错,非严格模式会忽略

定义多个属性

Object.defineProperties(),该方法接收两个参数, 都是两个对象 , 第一个是要添加和修改属性的对象

第二个对象中的属性要与第一个对象中添加或修改的属性对应

例:

const people = {_name: 'Nigo',_age: 28
};Object.defineProperties(people , {_name: {value: 'HaHa',//可修改其他特性},name: { //定义一个访问器属性get() {return this._name;}},age: {set(newV) {this._age = newV}}
})

读取属性的特性

Object.getOwnPropertyDescriptor()

两个参数 属性所在的对象和要读取属性的属性名,该方法返回值是一个对象

如果是数据属性, 返回的对象中包含configurable、 enumerable、 writabele 、 value

如果是访问器属性,返回的对象中包含configurable 、 enumerable、 get 、 set

在JS中,可以对任何对象使用Object.getOwnPropertyDescriptor() 方法

Object.defineProperty()个人理解相关推荐

  1. [vue] 说说你对Object.defineProperty的理解

    [vue] 说说你对Object.defineProperty的理解 Object.defineProperty定义新属性或修改原有的属性: vue的数据双向绑定的原理就是用的Object.defin ...

  2. 对javscript中Object.defineProperty的理解

      自己在使用vue的过程中经常会用到听到数据双向绑定这个词,而且我们还可以直接通过调用this.msg(this表示vue实例),来获取data上的数据,以前一直不太明白为什么可以这样获取,直到有一 ...

  3. Object.defineProperty的理解

    一.Object.defineProperty:给一个对象定义一个新的属性或修改一个对象现有的属性,并且返回这个对象 1.语法:Object.defineProperty(参数1,参数2,参数3) 参 ...

  4. 如何理解JavaScript中Object.defineProperty【一】

    前言 当我们了解一个方法时,建议从以下几个维度着手 1.方法的定义 2.了解方法的使用场景 3.在场景中解决什么问题 带着这样的好奇心,去学习.研究,我们可能更好的理解.掌握.运用它 复制代码 定义 ...

  5. 理解Object.defineProperty的作用

    对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值. 定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...

  6. 关于Object.defineProperty中enumerable: false不可枚举的理解

    文章目录 能否被for-in循环 对象的可枚举性除了会影响for-in还会影响Object.keys()和JSON.stringify方法 Object.defineProperty的enumerab ...

  7. vue 数据绑定实现的核心 Object.defineProperty()

    vue深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简 ...

  8. Object.defineProperty与双向绑定、数据监听

    一.对象赋值的两种方式 一是"="赋值,一是Object.defineProperty方法,而当下流行框架中广泛应用的双向绑定和数据监听等,就是利用的第二种方式,关于此方法不多讲, ...

  9. 基于Object.defineProperty实现双向数据绑定

    双向数据绑定可算是前端领域经久不衰的热词,不管是前端开发还是面试都会有所涉及.而且不同的框架也想尽一切办法去实现这一特性,比如: Knockout / Backbone --- 发布-订阅模式 Ang ...

最新文章

  1. sqlserver查询自定义的函数
  2. 看一名 KDE 开发者如何使用 C++17 为项目提升巨大速度
  3. MFC文件打开和保存
  4. 51单片机常用寄存器速查
  5. 系统需求分析文档需要考虑的问题
  6. 作为开发,你对进程和线程能否区分开来呢?
  7. 动荡的 Docker
  8. 拓端tecdat|在R语言中显示美丽的数据摘要summary统计信息
  9. 利用C#实现Pdf转图片
  10. 计算机视觉--图像导数-图像梯度向量
  11. ubuntu如何看到隐藏文件夹
  12. JavaScript基础Date函数
  13. Python:实现scoring functions评分函数算法(附完整源码)
  14. 夏令营+预推免小结(中南 东南 浙大)
  15. Java基础系列35-IO流
  16. Shell命令-文件及目录操作之pwd、rm
  17. 【Java版oj】逆波兰表达式求值
  18. pdf阅读器如何语音朗读文件
  19. Hash——字符串Hash
  20. 【文献阅读】PSO混合GA解决不确定IPPS问题

热门文章

  1. C++打卡1-夫妇和驴
  2. svnsync: Failed to get lock on destination repos, currently held by 'localhost.localdomain
  3. ZCMU 1600: 卡斯丁狗要吃糖葫芦
  4. API NetUserChangePassword Did yer sd1
  5. 拉勾前端高薪就业课程笔记第十一弹(模块4-1)
  6. Android手机在4G网络环境下IP的识别
  7. 阿里 P7 前端高级工程师,都需要掌握哪些技术栈?做为学习方向上的借鉴和参考
  8. 思想学习——细节决定成败
  9. 打包aab_聚餐买单AA制已经过时了 AAB制、AABB制、BBK制,你选哪个?
  10. 【中文】【吴恩达课后编程作业】Course 4 - 卷积神经网络 - 第二周作业