栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JS 实现对象监听 - Kaiqisan

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JS 实现对象监听 - Kaiqisan

JS 实现对对象内参数的监听

哈嗨哈,这里是超会拖更的Kaiqisan,自从成为社畜之后就很少有空撰写博客了,今天下午后端那边服务器在维修,这就给了我很多整理博客的时间(摸鱼?)

使用过vue的人都知道vue拥有对参数监听的便捷方法,其原理就是使用数据劫持,在每次数据产生变化的时候触发其内在的函数,其书写方式如下

// 第一个参数填写欲监听的对象
// 第二个参数填写欲监听的对象下的属性
Object.defineProperty(obj, 'attr', {
	get() {
		return val
    },
	set(newValue) {
        console.log('触发!');
		val= newValue
    }
})

监听的功能通过上述的Object.defineProperty来实现,并借助了其第三个参数----属性描述符完成数据劫持,每次获取或修改数据,都将走过这一步,这也是vue的监听实现的底层逻辑。

如果开发者不设置这个高级选项,那么也就是进行一个默认的选项,getter默认返回当前对象的值,setter默认在修改值之后不进行任何操作。

下面的代码为具体的一个实例

	let obj = {
        name: 'John',
        uid: '12345',
    }
    let _uid = obj.uid;

    Object.defineProperty(obj, 'uid', {
		get() {
			return _uid
        },
		set(newValue) {
            console.log('触发!');
			_uid = newValue
        }
    })
    // 测试代码
	setTimeout(() => {
		obj.uid = '54321'
		console.log(obj.uid);
	}, 3000)

在打开页面之后的三秒后,输出框会自动修改对象的值并触发setter内的事件。
其中值得注意的是上面的一个临时参数_uid,这个参数的作用就在用户获取uid的时候能够获取正确的数据。
因为一些内在原因,getter和setter无法调用自己所监听的对象属性。

所以需要借助第三方的参数_uid来实现对象属性值的存储。

注意

这个监听的方法不仅可以实现对属性值的监听,也可以监听整个对象,如果对象内部的值产生变化就会回调setter。

    let obj = {
        name: 'John',
        uid: '12345',
		details: {
            phoneNumber: '1234567890',
		}
    }
    let details = obj.details;

    Object.defineProperty(obj, 'details', {
		get() {
			return details
        },
		set(newValue) {
            console.log('触发!');
			details = newValue
        }
    })
	setTimeout(() => {
		// 修改了obj.details内部的手机号
		obj.details.phoneNumber= '12345678901'
		console.log(obj.details);
	}, 3000)
扩展

上述的方法虽然能监听对象内部的属性值的变化,如果只是监听外部的对象,是很难具体获取内部的哪个属性值发生了变化。这个还需后序的比较,非常麻烦,所以,JS原生还有一种方法可以批量地监听,这不仅能够监听对象内部的多个属性,也可以极大地减少代码量。

这个方法就是使用Object.defineProperty所衍生的Object.defineProperties

    let obj = {
        name: 'John',
        uid: '12345',
        phoneNumber: '123456789',
    }
    let name = obj.name
    let uid = obj.uid
    let phoneNumber = obj.phoneNumber

    Object.defineProperties(obj, {
        'name': {
            get() {
                return name
            },
            set(value) {
                console.log('名字发生变化' + value)
                name = value
            }

        },
        'uid': {
            get() {
                return uid
            },
            set(value) {
                console.log('uid发生变化' + value)
                uid = value
            }
        },
        'phoneNumber': {
            get() {
                return phoneNumber
            },
            set(value) {
                console.log('phoneNumber发生变化' + value)
				phoneNumber = value
            }
        }
    })

    setTimeout(() => {
        obj.name = 'Tom'
	}, 1000)

	setTimeout(() => {
		obj.uid = '123456'
	}, 2000)
	
	setTimeout(() => {
		obj.phoneNumber = '123456789'
	}, 3000)
总结

好了,我们了解了监听的底层逻辑了,是时候自己模拟一遍vue的watch的方法了!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/987930.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号