双向绑定Proxy VS Object.defineProperty
Vue3.0的双向绑定将使用Proxy代替Object.defineProperty,据尤大说,速度提升了1倍。
本文我们来探讨一下Proxy对比Object.defineProperty究竟有哪些优劣呢?

首先介绍一下什么是Proxy?
Proxy在ES6规范中被正式发布,Proxy可以理解成在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。
Proxy语法:
ES6原生提供Proxy构造函数,用来生成Proxy实例
var proxy = new Proxy(target,handler);
Proxy接受两个参数:
target:要代理目标对象
handler: 处理函数,该函数将拦截对应的操作
下面是 Proxy 支持的拦截操作一览,一共 13 种。
- get(target, propKey, receiver):拦截对象属性的读取,比如
proxy.foo和proxy['foo']。 - set(target, propKey, value, receiver):拦截对象属性的设置,比如
proxy.foo = v或proxy['foo'] = v,返回一个布尔值。 - has(target, propKey):拦截
propKey in proxy的操作,返回一个布尔值。 - deleteProperty(target, propKey):拦截
delete proxy[propKey]的操作,返回一个布尔值。 - ownKeys(target):拦截
Object.getOwnPropertyNames(proxy)、Object.getOwnPropertySymbols(proxy)、Object.keys(proxy)、for...in循环,返回一个数组。该方法返回目标对象所有自身的属性的属性名,而Object.keys()的返回结果仅包括目标对象自身的可遍历属性。 - getOwnPropertyDescriptor(target, propKey):拦截
Object.getOwnPropertyDescriptor(proxy, propKey),返回属性的描述对象。 - defineProperty(target, propKey, propDesc):拦截
Object.defineProperty(proxy, propKey, propDesc)、Object.defineProperties(proxy, propDescs),返回一个布尔值。 - preventExtensions(target):拦截
Object.preventExtensions(proxy),返回一个布尔值。 - getPrototypeOf(target):拦截
Object.getPrototypeOf(proxy),返回一个对象。 - isExtensible(target):拦截
Object.isExtensible(proxy),返回一个布尔值。 - setPrototypeOf(target, proto):拦截
Object.setPrototypeOf(proxy, proto),返回一个布尔值。如果目标对象是函数,那么还有两种额外操作可以拦截。 - apply(target, object, args):拦截 Proxy 实例作为函数调用的操作,比如
proxy(...args)、proxy.call(object, ...args)、proxy.apply(...)。 - construct(target, args):拦截 Proxy 实例作为构造函数调用的操作,比如
new proxy(...args)。
下面介绍两个常用的拦截方法:get方法和set方法。
//get方法用于拦截某个属性的读取操作
//接受三个参数,依次为目标对象、属性名和Proxy实例本身,最后一个参数可选 //set方法用于拦截某个属性的赋值操作
//接受四个参数,一次为目标对象、属性名、属性值和Proxy实例本身,最后一个参数可选 var person = {
name:'Jack',
age:20
};
var handler = {
get(target,key){
if(key in target){
console.log(`${key}被读取`);
return target[key]
}else{
throw new ReferenceError(`Property ${key} does not exist`)
}
},
set(target,key,value){
console.log(`${key}被设置为${value}`)
target[key] = value
}
};
let instance = new Proxy(person,handler);
instance.name //name被读取
instance.age = 25 //age被设置为25
Object.defineProperty缺点:
1. 对数组的支持不好,无法监听到数组的变化,在Vue官方文档说明了可以监听到数组的变动,但只限于push、pop、shift、unshift、splice、sort、reverse方法。实际上是他们对这几种方法进行了重写。
var arrayProto = Array.prototype;
var arrayMethods = Object.create(arrayProto);
[
'push',
'pop',
'shift',
'unshift',
'splice',
'sort',
'reverse'
].forEach(function(item){
Object.defineProperty(arrayMethods,item,{
value:function mutator(){
//缓存原生方法,之后调用
console.log('array被访问');
var original = arrayProto[item]
var args = Array.from(arguments)
original.apply(this,args)
// console.log(this);
},
})
})
2.Object.defineProperty监听的是对象的属性,当一个对象为深层嵌套的时候,必须进行递归遍历,比较麻烦。
Proxy对比Object.defineProperty:
优点:
1. Proxy可以劫持整个对象,这样以来操作便利程度远远优于Object.defineProperty。
2. Proxy可以直接监听数组的变化,无需进行数组方法重写。
var arr = [1,2,3,4];
var instance = new Proxy(arr,{
get(target,key){
console.log('数组被读取')
return Reflect.get(target,key)
},
set(target,key,val){
console.log('监听到数组更新')
return Reflect.set(target,key,val)
}
}) instance[0] = 5 //监听到数组更新
instance.push(6) //数组被读取 监听到数组更新
3. Proxy支持13种拦截操作,是Object.defineProperty不具备的。
缺点:Proxy的兼容性不是太好,不兼容IE,且无法通过polyfill提供兼容。
双向绑定Proxy VS Object.defineProperty的更多相关文章
- 【Vue】-- 数据双向绑定的原理 --Object.defineProperty()
Object.defineProperty()方法被许多现代前端框架(如Vue.js,React.js)用于数据双向绑定的实现,当我们在框架Model层设置data时,框架将会通过Object.def ...
- MVVM双向绑定实现之Object.defineProperty
随着web应用的发展,直接操作dom的应用已渐行渐远,取而代之的是时下越来越流行的MVVM框架,dom操作几乎绝迹,这里面自然是框架底层封装的结果.MVVM框架的双向数据绑定使开发效率大大提高:然后在 ...
- 实现双向绑定Proxy比defineproperty优劣如何?
前言 双向绑定其实已经是一个老掉牙的问题了,只要涉及到MVVM框架就不得不谈的知识点,但它毕竟是Vue的三要素之一. Vue三要素 响应式: 例如如何监听数据变化,其中的实现方法就是我们提到的双向绑定 ...
- vue实现双向绑定的简单原理: defineProperty
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- vue双向数据绑定的原理-object.defineProperty() 用法
有关双向数据绑定的原理 关于数据双向绑定的理解:利用了 Object.defineProperty() 这个方法重新给对象定义了新属性,在操作新属性分别为为获取属性值(调用get方法)和设置属性值(调 ...
- 双向数据绑定实现之Object.defineProperty
vue.js利用的是es5的 defineproperty 特性实现的双向数据绑定,了解一下基本原理. 举例 var person= {}; Object.defineProperty(person, ...
- vuejs的双向数据绑定实现原理——object.defineproperty()
视图和数据变化绑定 而vue.js主要利用了accessor descriptors的set和get来更新视图,这里看到的这个例子挺好,是一个简单的绑定.对于一个html页面 <div> ...
- 浅谈Vue之双向绑定
VUE实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的.那么Object.defineP ...
- Vue2.0实现双向绑定的原理
一.几种实现双向绑定的做法 目前几种主流的mvc(vm)框架都实现了单向数据绑定,而我所理解的双向数据绑定无非就是在单向绑定的基础上给可输入元素(input.textare等)添加了change(in ...
随机推荐
- 异数OS 织梦师-水桶(三)-- RAM共享存储方案
. 异数OS 织梦师-水桶(三)– RAM共享存储方案 本文来自异数OS社区 github: https://github.com/yds086/HereticOS 异数OS社区QQ群: 652455 ...
- [bzoj4825] [loj#2018] [Hnoi2017] 单旋
Description \(H\) 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(\(splay\))是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构 ...
- [bzoj5507] [洛谷P5305] [gzoi2019]旧词
Descriptioin 浮生有梦三千场 穷尽千里诗酒荒 徒把理想倾倒 不如早还乡 温一壶风尘的酒 独饮往事迢迢 举杯轻思量 泪如潮青丝留他方 --乌糟兽/愚青<旧词> 你已经解决了五个问 ...
- [bzoj4824][洛谷P3757][Cqoi2017]老C的键盘
Description 老 C 是个程序员. 作为一个优秀的程序员,老 C 拥有一个别具一格的键盘,据说这样可以大幅提升写程序的速度,还能让写出来的程序 在某种神奇力量的驱使之下跑得非常快.小 Q 也 ...
- CDH大数据平台搭建终极版
经过无数次的失败,终于将CDH安装到两台普通的笔记本电脑上,主要失败原因有以下几点: 不熟悉安装过程,官方给出的安装方法有三种,所以都尝试了一遍,浪费了大量时间,所以有时候方法多不见得是一件好事. 安 ...
- 技术交流群和CSDN免费下载服务
1.最近很多新读者的关注,如果还没认识我或不清楚本公号能为你带来什么,可点击阅读你.我 2.本篇文章只为告诉新读者与不知道这些福利的旧读者 本公号其中为你提供的两大价值之处: 一个好的学习环境:技术交 ...
- doT 这个模板 是怎么实现的?
之前做过一个微信有关的站 模板用 doT 嗯 这个 用起来很 不错. 但是 它是怎么实现的,想过没有? ps:https://github.com/olado/doT 源码总共 140行. 第90行里 ...
- 在qemu-kvm配置桥接网络
为了宿主机和虚拟机可以很好的通信,当然是选择桥接网络啦!!! 话不多说 ===========================配置桥接网络========================== 虚拟机虽 ...
- BOM DOM 注意事項
setTimeout(js,時間) js处 应该放一个函数 不能放 alert confirm 等 (否则延时会失效) setTimeout() 和 setInterval() 的区别: ...
- Java并发专栏
1. Java并发 2. 守护线程与非守护线程 3. 为什么启动线程用start()而不用run()? 4. Java线程join方法总结 5. 生产者与消费者 6. wait.notify/noti ...