数据响应原理--1.Object.defineProperty

194 阅读2分钟

写在前面:本笔记来自于www.bilibili.com/video/BV1iX… 侵删

image.png 官网的图

MVVM

image.png MVVM,相信大家都知道吧

image.png 侵入式和非侵入式,Vue使用的是非侵入式,不需要使用API就可以改变数据。但是侵入式必须要调用特意的API才能够更改数据\

1.为什么MMVVM数据发生改变视图也会发生改变,也就是MVVM是怎么实现的?
  

image.png 也就是这个,为啥改变a,页面中视图也会被改变;

Object.defineProperty()函数

image.png image.png

对vue有了解的同学可能也对这个函数有一定了解,精密的系统也就是:

image.png

var obj={}

Object.defineProperty(obj,'a',{

value:3

// 该方法的意思是定义一个对象的属性的值,等同于obj.a=3;obj.b=4

})

Object.defineProperty(obj,'b',{

value:4

}) 

console.log(obj,obj.a,obj.b)

既然Object.defineProperty()方法和obj.a等一样,那么这个方法的优势在哪里呢,在于:

image.png

image.png

image.png 改成true之后obj.a++才会生效
也就是说,Object.defineProperty()可以设置额外隐藏的属性,这也是为啥js会提供这个方法的原因

除此之外:

image.png 表示是否可以被枚举,啥意思呢,我们都知道obj里面有a和b两个属性,

image.png a属性不能被枚举,但是b属性可以,此时:

image.png 我遍历obj中的所有属性,只能得到b,拿不到a

var obj={}

Object.defineProperty(obj,'a',{

value:3,

// 该方法的意思是定义一个对象的属性的值,等同于obj.a=3;obj.b=4,那么该方法的优势在哪里呢

writable:true,

enumerable:false

})

Object.defineProperty(obj,'b',{

value:4,

enumerable:true

})

obj.a++

console.log(obj,obj.a,obj.b)

for(var k in obj){

console.log(k)

}

======================================================

   所以,Object.defineProperty()这个方法可以让这个对象的属性能够被更自由的定义。

get/set(getter/setter)

只要去访问对象中的a属性,就会去读get函数

image.png 当然 此时obj上还有同时拥有a属性和b属性的,但是,此时输出obj对象,你是看不到b的:

image.png 因为换句话来说,由于value和get无法共存,你实际上是没有给b赋值成功的,也称之为数据劫持
同样的道理,你也可以对obj的b属性进行设置(修改)

image.png

image.png 访问+赋值(自增)
但是假如你是直接进行赋值

image.png

image.png 只改变不访问

总结:

尤大大发现的一个秘密:为什么vue是非侵入式?
因为a属性已经被set函数劫持了,当我们调用obj.a的时候,我们就会去访问这个属性,就会去试图改变obj.a属性,所以就会输出\

注意这个问题:

image.png

console.log(obj)

obj.b = 10

console.log(obj.b)
1.命名对obj.b赋值了,但是console.log(obj.b),你会神奇地发现,得到地数据是undefined

image.png