JavaScript全解析之面向对象——Object.defineProperty()
Object.defineProperty()
作用: 给对象添加一个属性并指定该属性的配置
语法: Object.defineProperty(obj, prop, descriptor)
obj: 要定义属性的对象。也就是给那个对象
prop: 要定义或修改的属性的名称或
descriptor: 要定义或修改的属性描述符,是一个对象。
value:该属性名对应的值
writable:该属性是否可以被重写(就是重新设置值)
-- 默认是 false 不允许被重写 , 也就是只读
-- 选填是 true 表示允许被重写 , 也就是可以被修改
enumerable: 表示该属性是否可以被枚举(遍历,其实也就是看 in 好不好使)
-- 默认是 false 不可以枚举
-- 选填是 true 表示可以遍历
get: 是一个函数 , 叫做getter获取器
-- 可以用来获取该属性的值
-- get函数的返回值就是这个属性的值
-- 注意: 不能和 value 和 writable 一起使用 , 会报错
set: 是一个函数 , 叫做setter设置器
-- 当你需要修改该属性值的时候 , 会触发该函数
// Object.defineProperty()
const obj = {}
console.log(obj) // 这个时候是一个空对象
// 设置
Object.defineProperty(obj,'age',{
value:18,
writable:true,
enumerable:true,
get () {
// 该函数的返回值就是这个属性的值
// 上面设置了value 和 writable 这里就不能返回了
return 20
},
set (val) {
console.log('你想要修改age的值,修改为:',val);
}
})
console.log(obj); // 打印结果: {age: 18}
// 之后我们尝试修改
// 修改我们之前的普通设置
obj.name = 'Rose'
console.log(obj); // 没有问题可以修改
// 修改通过Object.defineProperty设置的值
obj.age = 30
console.log(obj); // 打印出来的结果还是18 , 这个时候是不允许被修改的
// 在没有书写 enumerable 之前是不可以遍历出age的 , 书写了enumerable:true 以后是可以的
for (let k in obj) {
console.log(k);
}
// 测试get函数的返回值不能和 value 和 writable一起使用
console.log(obj)
Object.defineProperties()
作用: 给对象添加多个属性并分别指定它们的配置。
语法: Object.defineProperties(对象,{})
对象: 你要劫持的对象
{} : 需要配置的信息
{哪一个属性:{配置项}}
{哪一个属性:{配置项}}
配置项中的内容
value:该属性名对应的值
writable:该属性是否可以被重写(就是重新设置值)
-- 默认是 false 不允许被重写 , 也就是只读
-- 选填是 true 表示允许被重写 , 也就是可以被修改
enumerable: 表示该属性是否可以被枚举(遍历,其实也就是看 in 好不好使)
-- 默认是 false 不可以枚举
-- 选填是 true 表示可以遍历
get: 是一个函数 , 叫做getter获取器
-- 可以用来获取该属性的值
-- get函数的返回值就是这个属性的值
-- 注意: 不能和 value 和 writable 一起使用 , 会报错
set: 是一个函数 , 叫做setter设置器
-- 当你需要修改该属性值的时候 , 会触发该函数
// Object.defineProperties()
const obj = {name:'Jack',age:30}
console.log('原始obj:',obj);
// 开始劫持 把obj劫持到obj身上
// 拿到obj中的所有的key
for (let k in obj) {
// 开始劫持
Object.defineProperties(obj,{
// 这样操作会报错
// 一旦 obj.name 被修改
// 不停的获取不停的该 , 不停的改不停的获取
// 就会造成栈溢出
// name:{
// get () {
// return obj.name
// }
// }
// 步骤1: 我们需要复制一份属性出来(也就是备份一份)
// 我们这里需要拼接一个变量出来
// 假设:之前的属性是name , 我们复制出来的属性叫做:_name
// 语法: ['_' + 属性名] : {}
['_' + k] : {
value: obj[k],
writable: true
},
// 步骤2: 正式开始劫持(劫持的是我们备份的)
[k] : {
get () {
return this['_' + k]
},
set (val) {
this['_' + k] = val
// 渲染页面操作
console.log('你尝试修改 ' + k + ' 属性, 你要修改为 : ', val)
}
}
})
}
console.log('劫持后obj',obj);
// 尝试修改
obj.age = 66
/*
这样劫持的缺点
=> 就是只能劫持当前以前的数据
=> 如果劫持过后 , 后期动态插入的数据不好使(也就的不能再被劫持到)
=> vue2中使用的就是这个 , 要求数据一开始是给好的
*/
obj.gender = '男'
console.log(obj);
猜你喜欢LIKE
相关推荐HOT
更多>>servlet底层原理是什么?
1、ServletAPI核心类与接口2、Servlet类处理请求的流程创建servlet类的步骤:创建一个命名为TestServlet继承javax.servlet.http.HttpServlet类详情>>
2023-05-30 10:41:22多线程的优势与劣势分别是什么?
多线程是指在同一个程序中,同时运行多个线程,每个线程都可以独立执行不同的任务,相互之间不会干扰。多线程的优势和劣势如下:优势:提高程序...详情>>
2023-05-30 10:32:12设计模式之生产者与消费者的代码实现
本文主要讲述生产者和消费者模式,文中会使用通俗易懂的案例,使你更好地学习本章知识点并理解原理,做到有道无术。什么是生产者和消费者模式生...详情>>
2023-05-30 10:25:46从零开始学Java之interface接口
一.接口简介简介Java中的接口(interface)类似于是一种特殊的抽象类,它也是众多抽象方法的集合。接口的定义方式、组成部分都与抽象类相似,却比...详情>>
2023-05-29 11:26:17热门推荐
如何进行mysql数据备份?
沸什么是servlet的生命周期?servlet请求处理流程是怎样的?
热servlet底层原理是什么?
热怎样编写java程序?
新多线程的优势与劣势分别是什么?
ssm框架的作用与原理是什么?
设计模式之生产者与消费者的代码实现
接口和抽象类有什么区别?4个方面对比
从零开始学Java之interface接口
从零开始学Java之Java中的内部类是怎么回事?
一分钟带你了解MySQL——基础与介绍
在java中,super关键字怎样使用
什么是事件流以及事件流的传播机制 ?
弹性盒有哪些属性是在父元素身上?