居士做网站,企业网站策划文案,lol关键词查询,广州免费核酸检测地点一、Object.defineProperty()
文档#xff1a;Object.defineProperty() - JavaScript | MDN
作用#xff1a;对一个对象进行操作的方法。可以为一个对象增加一个属性#xff0c;同时也可以对一个属性进行修改和删除。 它是在 ES5 中引入的#xff0c;使用了 getter 和 s…
一、Object.defineProperty()
文档Object.defineProperty() - JavaScript | MDN
作用对一个对象进行操作的方法。可以为一个对象增加一个属性同时也可以对一个属性进行修改和删除。 它是在 ES5 中引入的使用了 getter 和 setter 方法来实现 Vue2 的响应式。 1、劣势
Object.defineProperty() 的问题主要有三个
不能监听数组的变化 无法监控到数组下标的变化导致通过数组下标添加元素不能实时响应 必须遍历对象的每个属性 只能劫持对象的属性从而需要对每个对象每个属性进行遍历。 如果属性值是对象还需要深度遍历。Proxy 可以劫持整个对象并返回一个新的对象 必须深层遍历嵌套的对象 2、优势 兼容性好支持 IE9 而 Proxy 的存在浏览器兼容性问题而且无法用 polyfill 磨平 3、代码 Object.defineProperty(obj, prop, descriptor);// obj 要定义属性的对象// prop 要定义或修改的属性的名称// descriptor 要定义或修改的属性描述符Object.defineProperty(obj, name, {value: 小草莓, // 初始值writable: true, // 该属性是否可写入enumerable: true, // 该属性是否可被遍历得到for...in Object.keys等configurable: true, // 定该属性是否可被删除且除writable外的其他描述符是否可被修改get: function () {},set: function (newVal) {},}); 二、proxy
1、对 Proxy 的理解
Proxy 可以理解成在目标对象之前架设一层“拦截”外界对该对象的访问都必须先通过这层拦截因此提供了一种机制可以对外界的访问进行过滤和改写。
Proxy 这个词的原意是代理用在这里表示由它来“代理”某些操作可以译为“代理器”。 ES6 入门教程 var obj new Proxy({}, {get: function (target, propKey, receiver) {console.log(getting ${propKey}!);return Reflect.get(target, propKey, receiver);},set: function (target, propKey, value, receiver) {console.log(setting ${propKey}!);return Reflect.set(target, propKey, value, receiver);}
});obj.count 1
// setting count!
obj.count
// getting count!
// setting count!
// 2
上面代码对一个空对象架设了一层拦截重定义了属性的读取get和设置set行为。 2、语法
ES6 原生提供 Proxy 构造函数用来生成 Proxy 实例
var proxy new Proxy(target, handler);
第一个参数target参数表示所要拦截的目标对象
第二个参数handler参数也是一个对象用来定制拦截行为。 它是一个配置对象对于每一个被代理的操作需要提供一个对应的处理函数该函数将拦截对应的操作。 Proxy 对象可以拦截目标对象的任意属性这使得它很合适用来写 Web 服务的客户端。 3、Proxy的优势
针对对象 针对整个对象而不是对象的某个属性 所以也就不需要对 keys 进行遍历 支持数组 Proxy 不需要对数组的方法进行重载省去了众多 hack减少代码量等于减少了维护成本而且标准的就是最好的 Proxy的第二个参数可以有 13 种拦截方法 不限于apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具备的 Proxy返回的是一个新对象 我们可以只操作新的对象达到目的。而Object.defineProperty只能遍历对象属性直接修改 Proxy作为新标准将受到浏览器厂商重点持续的性能优化 也就是传说中的新标准的性能红利 4、使用 proxy 创建一个响应式对象 import { isObject } from ./util; // 工具方法// 创建一个响应式对象export function reactive(target) {// 根据不同参数创建不同响应式对象return createReactiveObject(target, mutableHandlers);}// 根据不同参数创建不同响应式对象function createReactiveObject(target, baseHandler) {if (!isObject(target)) {return target;}const observed new Proxy(target, baseHandler);return observed;}const get createGetter();const set createSetter();function createGetter() {return function get(target, key, receiver) {// 对获取的值进行放射const res Reflect.get(target, key, receiver);console.log(属性获取, key);if (isObject(res)) {// 如果获取的值是对象类型则返回当前对象的代理对象return reactive(res);}return res;};}function createSetter() {return function set(target, key, value, receiver) {const oldValue target[key];const hadKey hasOwn(target, key);const result Reflect.set(target, key, value, receiver);if (!hadKey) {console.log(属性新增, key, value);} else if (hasChanged(value, oldValue)) {console.log(属性值被修改, key, value);}return result;};}export const mutableHandlers {get, // 当获取属性时调用此方法set // 当修改属性时调用此方法}; 三、问题
1、Proxy只会代理对象的第一层那么 Vue3 又是怎样处理这个问题的呢 判断当前 Reflect.get 的返回值是否为 Object 如果是则再通过 reactive 方法做代理 这样就实现了深度观测。 2、监测数组的时候可能触发多次get/set那么如何防止触发多次呢
我们可以判断 key 是否为当前被代理对象 target 自身属性也可以判断旧值与新值是否相等只有满足以上两个条件之一时才有可能执行 trigger 四、Vue3.0 里为什么要用 Proxy 替代 defineProperty ?
主要是从性能方面考量 defineProperty该 API 存在一些局限性比如对于数组的拦截有问题为此 Vue 需要专门为数组响应式做一套实现。另外不能拦截那些新增、删除属性。最后 defineProperty 方案在初始化时需要深度递归遍历待处理的对象才能对它进行完全拦截明显增加了初始化的时间。 以上两点在 Proxy 出现之后迎刃而解。 Proxy不仅可以对数组实现拦截还能对 Map、Set 实现拦截。另外 Proxy 的拦截也是懒处理行为。如果用户没有访问嵌套对象那么也不会实施拦截这就让初始化的速度和内存占用都改善了。 Vue的代理也是最开始只代理最外层的对象在访问的时候去判断是否为一个 object然后再去用 proxy 包裹 当然 Proxy 是有兼容性问题的IE 完全不支持所以如果需要 IE 兼容就不合适 五、底层拦截原理 六、Proxy 和 Object.defineProperty 的区别
Vue2 和 Vue3 响应式上有什么区别 / 使用 Object.defineProperty() 来进行数据劫持有什么缺点_vue 2响应式和vue 3响应式区别-CSDN博客
都可以用来实现 JavaScript 对象的响应式但是它们有一些区别
① 实现方式 Proxy 是 ES6 新增的一种特性使用了一种代理机制来实现响应式。 Object.defineProperty 是在 ES5 中引入的使用了 getter 和 setter 方法来实现。 ② 作用对象 Proxy 可以代理整个对象包括对象的所有属性、数组的所有元素以及类似数组对象的所有元素。 Object.defineProperty 只能代理对象上定义的属性。 ③ 监听属性 Proxy 可以监听到新增属性和删除属性的操作 Object.defineProperty 只能监听到已经定义的属性的变化。 ④ 性能 由于 Proxy 是 ES6 新增特性其内部实现采用了更加高效的算法相对于 Object.defineProperty来说在性能方面有一定的优势。 综上所述虽然 Object.defineProperty 在 Vue.js 2.x 中用来实现响应式但是在 Vue.js 3.0 中已经采用了 Proxy 来替代。
这是因为 Proxy 相对于 Object.defineProperty 拥有更优异的性能和更强大的能力。