<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>Observe demo</title></head><body>    <p>响应式 demo</p>    <script src="./observe.js"></script></body></html>
function updateView(val) {    console.log('视图更新', val)}// 从新定义数组原型const arrayProto = Array.prototype// 创立新对象,原型指向 arrayProto ,再扩大新的办法不会影响原型const arrayMethods = Object.create(arrayProto);['push', 'pop', 'shift', 'unshift', 'sort', 'reverse', 'splice'].forEach(methodName => {    arrayMethods[methodName] = function() {        arrayProto[methodName].call(this, ...arguments)        updateView(this)    }})// 监听对象属性function observer(target) {    // 不是对象或数组,间接返回    if (typeof target !== 'object' || target == null) return target    if (Array.isArray(target)) {        target.__proto__ = arrayMethods    } else {        // 从新定义各个属性(for in 也能够遍历数组)        for(let key in target) {            defineReactive(target, key, target[key])        }    }}// 监听属性的get和setfunction defineReactive(target, key, val) {    // 递归监听子属性(深度监听)    observer(val)    Object.defineProperty(target, key, {        get() {            return val        },        set(newVal) {            if (newVal !== val) {                updateView(newVal)                return newVal            }        }    })}const data = {    name: '张三',    age: 20,    obj: {        address: '北京'    },    a: {        b: {            c: {                d: 'dddddddd'            }        }    },    nums: [4,6,2,7,4,8,1]}// 监听dataobserver(data)data.name = '李四'data.age = 33data.obj.address = '深圳'data.a.b.c.d = 'd 扭转了'data.nums.push(6)data.nums.reverse()data.nums.sort((a, b) => a - b)