Object.defineProperty() 和 ES2015 中新增的 Proxy 对象,会经常用来做数据劫持.
数据劫持:在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作或者修改返回结果.数据劫持最典型的应用———双向的数据绑定
- Vue 2.x 利用 Object.defineProperty(),并且把内部解耦为 Observer, Dep, 并使用 Watcher 相连
- Vue 在 3.x 版本之后改用 Proxy 进行实现
Object.defineProperty()
**Object.defineProperty()**方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。语法
用法
var a= {}Object.defineProperty(a,"b",{set:function(newValue){console.log("你要赋值给我 我的新值是"+newValue)a['b'] = newValue;},get:function(){console.log("你取我的值")return a['b']}})a.b = 1 // 赋值,触发set方法console.log(a.b) // 调用值,触发get方法
优点
兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平
缺点
不能监听数组的变化
- 必须遍历对象的每个属性
-
Proxy
Proxy 对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。
语法
用法
let obj = {name: 'Eason',age: 30}let handler = {get (target, key, receiver) {console.log('get', key)return Reflect.get(target, key, receiver)},set (target, key, value, receiver) {console.log('set', key, value)return Reflect.set(target, key, value, receiver)}}let proxy = new Proxy(obj, handler)proxy.name = 'Zoe' // set name Zoeproxy.age = 18 // set age 18
优点
Proxy 可以直接监听对象而非属性;
- Proxy 可以直接监听数组的变化;
- Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
- Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
缺点
Proxy 的兼容性不如 Object.defineProperty() (caniuse 的数据表明,QQ 浏览器和百度浏览器并不支持 Proxy,这对国内移动开发来说估计无法接受,但两者都支持 Object.defineProperty())
- 不能使用 polyfill 来处理兼容性
