您的当前位置:首页正文

vue中的数据劫持

2024-11-08 来源:个人技术集锦

本篇只是我对尚硅谷张老师课程代码自己做的一个注释,只是一个学习笔记,所以要结合视频看才行啊 

课程视频(看33和34节) 

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Document</title>
	</head>
	<body>
		<script type="text/javascript" >

			let data = {    //定义变量data,然后把对象{name:'尚硅谷',address:'北京'}的内存地址存放进变量data中
				name:'尚硅谷',
				address:'北京'
			}

            

			//创建一个监视的实例对象,用于监视data中属性的变化
			const obs = new Observer(data)	//第1步,把变量data(里边存的是对象的地址)传递给构造函数,其实就是把对象{name:'尚硅谷',address:'北京'}的地址传递给构造函数
			console.log(obs)	

			//准备一个vm实例对象
			let vm = {}
            //第4步,这里data的被修改了,也就是说它里边存放的不再是对象{name:'尚硅谷',address:'北京'}的内存地址了。 
            //但是get和set仍然可以通过obj操作对象{name:'尚硅谷',address:'北京'},这是由于闭包的原因。
			vm._data  = data = obs  

			function Observer(obj){    //第2步,把data赋值给参数obj,也就是参数obj和data指向相同的内存空间,就是对象{name:'尚硅谷',address:'北京'}的内存地址。
				//汇总对象中所有的属性形成一个数组
				const keys = Object.keys(obj)
				//遍历
				keys.forEach((k)=>{
					Object.defineProperty(this,k,{
                        //第3步:闭包。obj是局部变量,它的作用域和生命周期都只限于Observer函数内部。
                        //当Observer函数执行完毕时,obj会被回收,但是它的引用还被get函数和set函数所持有,这就形成了一个闭包。
                        //所以,即使obj被回收了,你仍然可以通过get函数和set函数来访问和修改obj的值。
						get(){     
							return obj[k]   
						},
						set(val){
							console.log(`${k}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了`)
							obj[k] = val
						}
					})
				})
			}

            /**
             * 傻强对数据劫持的总结:
             * 经过上边的一段操作后,最终的效果是这样的:
             * 1,对象obs里,拥有“原来的data所指向的对象{name:'尚硅谷',address:'北京'}”中的所有属性。但,它的每一个属性都有get和set方法。
             * 2,变量data已经不再指向原来的对象{name:'尚硅谷',address:'北京'}了。变量data和vm._data指向obs对象,所以当我们读写vm._data.name和data.name的时候,就是读写obs.name,obs对象中的get和set方法会被调用。
             * 3,当obs中的get和set被调用的时候,会操作局部变量obj指向的对象,局部变量obj中存放的一直都是“原来的对象{name:'尚硅谷',address:'北京'}”的内存地址,虽然obj是局部参数,但由于闭包的原因,局部变量obj不会被释放,它一直存放着“原来的对象{name:'尚硅谷',address:'北京'}”的内存地址,所以可以修改原来的对象的属性值。
             * 4,每当我们通过vm._data或变量data读写“原来的对象{name:'尚硅谷',address:'北京'}中的属性”都会经过set和get,所以叫做数据劫持!
             * 5,数据劫持的目的就是在get和set中,加上一写代码通知vue,数据被修改了。
             */

		</script>
	</body>
</html>

显示全文