数据属性描述符
var obj = {
name: "xxx",
age: 18,
};
Object.defineProperty(obj, "name", {
configurable: false, //告诉js引擎,obj.name不能被删除
enumerable: false, //告诉js引擎,obj.name属性不能被枚举(for in/Object.keys())
writable: false, //告诉js引擎,obj对象的name属性不写入(只读属性readonly)
value: "xxx", //告诉js引擎,返回这个value
});
其中,第三个参数有一些配置项。
-
configurable告诉js引擎,obj.name能否被删除
-
enumerable告诉js引擎,obj.name属性能否被枚举(for in/Object.keys())
-
writable 告诉js引擎,obj对象的name属性能否被写入(只读属性readonly)
-
value 告诉js引擎,返回这个value
存储属性描述符
var obj = { name: "xxx" };
var _name = "";
Object.defineProperty(obj, "name", {
configurable: true,
enumerable: false,
set: function (value) {
_name = value;
console.log("set", value);
},
get: function () {
console.log("get");
return _name;
},
});
当我们读取obj.name的时候,会触发get() 当我们修改obj.name的时候,会触发set()
发布订阅模式
-
1.vue响应原理: vue.js采用数据劫持结合
发布-订阅者模式,通过Object.defineProperty()来劫持data中各个属性的setter、getter,在数据变动时,发布消息给订阅者,触发响应的监听回调。 -
2、发布-订阅者模式的作用:
处理一对多的场景,应用于不同情况下的不同函数调用
优点:低耦合性,易于代码维护;
缺点:若订阅的消息未发生,需消耗一定的时间和内存。
其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知
vue2
vue2的响应式原理主要使用的是Object.defineProperty( ) ,里面需要传入三个参数,分别是:
【响应源数据的对象,源数据中的需要读写的属性,相对应的对象方法(包含了get和set方法)】
<script>
// 存储属性描述符
// vue2响应式原理
var obj = { name: "xxx" };
var _name = "";
Object.defineProperty(obj, "name", {
configurable: true,
set: function (value) {
console.log("调用了set方法,修改了name属性");
obj.name = value;
},
get: function () {
console.log("调用了get方法,获取了name属性");
return obj.name;
},
});
//调用Object.defineProperty中的get方法获取数据
console.log(obj.name);
//调用Object.defineProperty中的set方法修改数据
obj.name = "张三";
</script>
在上面的示例中,我们利用了JS对象中的defineProperty()方法对对象person进行了数据劫持。
vue响应式也叫作数据双向绑定,大致原理阐述:
-
首先我们需要通过Object.defineProperty()方法把数据(data)设置为getter和setter的访问形式,这样我们就可以在数据被修改时在setter方法设置监视修改页面信息,也就是说每当数据被修改,就会触发对应的set方法,然后我们可以在set方法中去调用操作dom的方法。
-
此外,如果页面有input用v-model绑定数据,我们需要在这种绑定了data的input元素上添加监听,添加input事件监听,每当input事件被触发时,就修改对应的data。
vue实现数据响应式,是通过数据劫持侦测数据变化,发布订阅模式进行依赖收集与视图更新,换句话说是Observe,Watcher以及Compile三者相互配合,
- Observe实现数据劫持,递归给对象属性,绑定setter和getter函数,属性改变时,通知订阅者
- Compile解析模板,把模板中变量换成数据,绑定更新函数,添加订阅者,收到通知就执行更新函数
- Watcher作为Observe和Compile中间的桥梁,订阅Observe属性变化的消息,触发Compile更新函数
VUE2.0响应式数据存在的缺陷
-
从上面看下来,你已经知道了,在vue2.0中,响应式原理使用了- Object.definedProprety实现了数据响应式。但是Object.definedProperty还存在了一定的缺陷。
-
无法监听到对象属性的动态添加和删除 无法监听到数组下标和length长度的变化
所以vue2.0中提供给了我们 $get $set $delete这些方法用来弥补不足
总结vue2响应式原理
是利用defineproperty来实现具体来说是对data里的属性都设置了getter 和setter,
- getter收集依赖就是收集每个标签和每个数据属性的对应关系,
- 当data对象中属性修改赋值的时候就会触发对应的setter函数拦截进行视图更新。