当前位置:网站首页>Object.defineProperty也能监听数组变化?
Object.defineProperty也能监听数组变化?
2022-06-25 07:44:00 【InfoQ】
本文简介
Object.definePropertyVue2Object.definePropertyObject.definePropertyVue2基础用法
Object.defineProperty()语法
Object.defineProperty(obj, prop, descriptor)
obj要定义属性的对象。
prop要定义或修改的属性的名称或Symbol。
descriptor要定义或修改的属性描述符。
const data = {}
let name = '雷猴'
Object.defineProperty(data, 'name', {
get() {
console.log('get')
return name
},
set(newVal) {
console.log('set')
name = newVal
}
})
console.log(data.name)
data.name = '鲨鱼辣椒'
console.log(data.name)
console.log(name)
get
雷猴
set
鲨鱼辣椒
鲨鱼辣椒
data.namenamenamedata.namenameconst data = {}
Object.defineProperty(data, 'name', {
value: '雷猴',
writable: false
})
data.name = '鲨鱼辣椒'
delete data.name
console.log(data.name)
data.namedata.name雷猴Object.defineProperty深度监听
// 触发更新视图
function updateView() {
console.log('视图更新')
}
// 重新定义属性,监听起来(核心)
function defineReactive(target, key, value) {
// 深度监听
observer(value)
// 核心 API
Object.defineProperty(target, key, {
get() {
return value
},
set(newValue) {
if (newValue != value) {
// 深度监听
observer(newValue)
// 设置新值
// 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
value = newValue
// 触发视图更新
updateView()
}
}
})
}
// 深度监听
function observer(target) {
if (typeof target !== 'object' || target === null) {
// 不是对象或数组
return target
}
// 重新定义各个属性(for in 也可以遍历数组)
for (let key in target) {
defineReactive(target, key, target[key])
}
}
// 准备数据
const data = {
name: '雷猴'
}
// 开始监听
observer(data)
// 测试1
data.name = {
lastName: '鲨鱼辣椒'
}
// 测试2
data.name.lastName = '蟑螂恶霸'
updateViewDOMVueObject.definePropertysetobserver(newValue)observerdefineReactive监听数组
key下标- 判断要监听的数据是否为数组
- 是数组的情况,就将数组模拟成一个对象
- 将数组的方法名绑定到新创建的对象中
- 将对应数组原型的方法赋给自定义方法
// 触发更新视图
function updateView() {
console.log('视图更新')
}
// 重新定义数组原型
const oldArrayProperty = Array.prototype
// 创建新对象,原形指向 oldArrayProperty,再扩展新的方法不会影响原型
const arrProto = Object.create(oldArrayProperty);
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
arrProto[methodName] = function() {
updateView() // 触发视图更新
oldArrayProperty[methodName].call(this, ...arguments)
}
})
// 重新定义属性,监听起来(核心)
function defineReactive(target, key, value) {
// 深度监听
observer(value)
// 核心 API
Object.defineProperty(target, key, {
get() {
return value
},
set(newValue) {
if (newValue != value) {
// 深度监听
observer(newValue)
// 设置新值
// 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
value = newValue
// 触发视图更新
updateView()
}
}
})
}
// 监听对象属性(入口)
function observer(target) {
if (typeof target !== 'object' || target === null) {
// 不是对象或数组
return target
}
// 数组的情况
if (Array.isArray(target)) {
target.__proto__ = arrProto
}
// 重新定义各个属性(for in 也可以遍历数组)
for (let key in target) {
defineReactive(target, key, target[key])
}
}
// 准备数据
const data = {
nums: [10, 20, 30]
}
// 监听数据
observer(data)
data.nums.push(4) // 监听数组
Array.prototype.push = function() {
updateView()
...
}
ArrayObject.defineProperty['push', 'pop', 'shift', 'unshift', 'splice']综合代码
// 深度监听
function updateView() {
console.log('视图更新')
}
// 重新定义数组原型
const oldArrayProperty = Array.prototype
// 创建新对象,原形指向 oldArrayProperty,再扩展新的方法不会影响原型
const arrProto = Object.create(oldArrayProperty);
// arrProto.push = function () {}
// arrProto.pop = function() {}
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
arrProto[methodName] = function() {
updateView() // 触发视图更新
oldArrayProperty[methodName].call(this, ...arguments)
}
})
// 重新定义属性,监听起来(核心)
function defineReactive(target, key, value) {
// 深度监听
observer(value)
// 核心 API
// Object.defineProperty 不具备监听数组的能力
Object.defineProperty(target, key, {
get() {
return value
},
set(newValue) {
if (newValue != value) {
// 深度监听
observer(newValue)
// 设置新值
// 注意,value 一直在闭包中,此处设置完之后,再 get 时也是会获取最新的值
value = newValue
// 触发视图更新
updateView()
}
}
})
}
// 监听对象属性(入口)
function observer(target) {
if (typeof target !== 'object' || target === null) {
// 不是对象或数组
return target
}
if (Array.isArray(target)) {
target.__proto__ = arrProto
}
// 重新定义各个属性(for in 也可以遍历数组)
for (let key in target) {
defineReactive(target, key, target[key])
}
}
总结
Vue 2缺点
- 深度监听,需要递归到底,一次计算量大
- 无法监听新增属性/删除属性(所以需要使用 Vue.set 和 Vue.delete)
- 无法原生监听数组,需要特殊处理
Vue 3Object.definePropertyProxyProxyVue 2Vue 3边栏推荐
- How to implement a system call
- Rank sum ratio (RSR) index calculation
- 【515. 在每个树行中找最大值】
- [515. find the maximum value in each tree row]
- Software engineering review questions
- Bluecmsv1.6- code audit
- 如何成为一名软件测试高手? 月薪3K到17K,我做了什么?
- How to calculate critical weight indicators?
- Hyper-v:Hyper-v 第 1 代或第 2 代虚拟机
- 如何实现一个系统调用
猜你喜欢

Super simple case: how to do hierarchical chi square test?

What are the indicators of entropy weight TOPSIS method?

How to design test cases

Various synchronous learning notes

View all listening events on the current page by browser
![[operation tutorial] how does the tsingsee Qingxi video platform import the old database into the new database?](/img/21/08194ac26dec50c222b88f1f64f894.png)
[operation tutorial] how does the tsingsee Qingxi video platform import the old database into the new database?

Check whether the point is within the polygon

leetcode. 13 --- Roman numeral to integer

Bluecmsv1.6- code audit

EasyPlayer流媒体播放器播放HLS视频,起播速度慢的技术优化
随机推荐
leetcode. 13 --- Roman numeral to integer
What is the difference between TP5 and tp6?
声纹技术(五):声纹分割聚类技术
How to do factor analysis? Why should data be standardized?
How to calculate critical weight indicators?
A 35 year old Tencent employee was laid off and sighed: a suite in Beijing, with a deposit of more than 7 million, was anxious about unemployment
声纹技术(一):声纹技术的前世今生
[reinforcement learning notes] common symbols in reinforcement learning
Incluxdb time series database
在网上股票开户安全吗?证券账户可以给别人用吗?
How is the ISM model analyzed?
Iframe is simple to use, iframe is obtained, iframe element value is obtained, and iframe information of parent page is obtained
如何实现一个系统调用
如何成为一名软件测试高手? 月薪3K到17K,我做了什么?
SharePoint:SharePoint 2013 with SP1 简易安装
如何设计测试用例
C language "recursive series": recursive implementation of 1+2+3++ n
Is the securities account given by Qiantang education business school safe? Can I open an account?
城链科技平台,正在实现真正意义上的价值互联网重构!
Nips 2014 | two stream revolutionary networks for action recognition in videos reading notes