Object.defineProperty()个人理解
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()个人理解相关推荐
- [vue] 说说你对Object.defineProperty的理解
[vue] 说说你对Object.defineProperty的理解 Object.defineProperty定义新属性或修改原有的属性: vue的数据双向绑定的原理就是用的Object.defin ...
- 对javscript中Object.defineProperty的理解
自己在使用vue的过程中经常会用到听到数据双向绑定这个词,而且我们还可以直接通过调用this.msg(this表示vue实例),来获取data上的数据,以前一直不太明白为什么可以这样获取,直到有一 ...
- Object.defineProperty的理解
一.Object.defineProperty:给一个对象定义一个新的属性或修改一个对象现有的属性,并且返回这个对象 1.语法:Object.defineProperty(参数1,参数2,参数3) 参 ...
- 如何理解JavaScript中Object.defineProperty【一】
前言 当我们了解一个方法时,建议从以下几个维度着手 1.方法的定义 2.了解方法的使用场景 3.在场景中解决什么问题 带着这样的好奇心,去学习.研究,我们可能更好的理解.掌握.运用它 复制代码 定义 ...
- 理解Object.defineProperty的作用
对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值. 定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...
- 关于Object.defineProperty中enumerable: false不可枚举的理解
文章目录 能否被for-in循环 对象的可枚举性除了会影响for-in还会影响Object.keys()和JSON.stringify方法 Object.defineProperty的enumerab ...
- vue 数据绑定实现的核心 Object.defineProperty()
vue深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简 ...
- Object.defineProperty与双向绑定、数据监听
一.对象赋值的两种方式 一是"="赋值,一是Object.defineProperty方法,而当下流行框架中广泛应用的双向绑定和数据监听等,就是利用的第二种方式,关于此方法不多讲, ...
- 基于Object.defineProperty实现双向数据绑定
双向数据绑定可算是前端领域经久不衰的热词,不管是前端开发还是面试都会有所涉及.而且不同的框架也想尽一切办法去实现这一特性,比如: Knockout / Backbone --- 发布-订阅模式 Ang ...
最新文章
- sqlserver查询自定义的函数
- 看一名 KDE 开发者如何使用 C++17 为项目提升巨大速度
- MFC文件打开和保存
- 51单片机常用寄存器速查
- 系统需求分析文档需要考虑的问题
- 作为开发,你对进程和线程能否区分开来呢?
- 动荡的 Docker
- 拓端tecdat|在R语言中显示美丽的数据摘要summary统计信息
- 利用C#实现Pdf转图片
- 计算机视觉--图像导数-图像梯度向量
- ubuntu如何看到隐藏文件夹
- JavaScript基础Date函数
- Python:实现scoring functions评分函数算法(附完整源码)
- 夏令营+预推免小结(中南 东南 浙大)
- Java基础系列35-IO流
- Shell命令-文件及目录操作之pwd、rm
- 【Java版oj】逆波兰表达式求值
- pdf阅读器如何语音朗读文件
- Hash——字符串Hash
- 【文献阅读】PSO混合GA解决不确定IPPS问题
热门文章
- C++打卡1-夫妇和驴
- svnsync: Failed to get lock on destination repos, currently held by 'localhost.localdomain
- ZCMU 1600: 卡斯丁狗要吃糖葫芦
- API NetUserChangePassword Did yer sd1
- 拉勾前端高薪就业课程笔记第十一弹(模块4-1)
- Android手机在4G网络环境下IP的识别
- 阿里 P7 前端高级工程师,都需要掌握哪些技术栈?做为学习方向上的借鉴和参考
- 思想学习——细节决定成败
- 打包aab_聚餐买单AA制已经过时了 AAB制、AABB制、BBK制,你选哪个?
- 【中文】【吴恩达课后编程作业】Course 4 - 卷积神经网络 - 第二周作业