// Create a reactive proxy
function reactive(target = {}) {
if (typeof target !== 'object' || target === 'null')
return target // Return directly if not an object or array
// Proxy configuration (traps)
const proxyConf = {
get(target, key, receiver) {
// Only handle own properties (non-prototype)
const ownKeys = Reflect.ownKeys(target)
ownKeys.includes(key) && console.log(/get/, key) // Log access
const result = Reflect.get(target, key, receiver)
// Lazy recursive call: only wrap nested objects when accessed
return reactive(result)
},
set(target, key, val, receiver) {
// Do not process if value is identical
if (val === target[key])
return true
const ownKeys = Reflect.ownKeys(target)
if (ownKeys.includes(key))
console.log(/set existing property/, key)
else
console.log(/set new property/, key)
const result = Reflect.set(target, key, val, receiver)
console.log(/set/, key, val)
return result // Return success boolean
},
deleteProperty(target, key) {
const result = Reflect.deleteProperty(target, key)
console.log(/deleteProperty/, key)
return result
},
}
// Generate the proxy object
return new Proxy(target, proxyConf)
}
// Test data
const data = {
name: 'Jack',
age: 24,
info: {
city: 'hangzhou',
a: { b: { c: { d: 1 } } },
},
}
const observed = reactive(data);