当前位置: 首页 > Web前端 > vue.js

Object.freeze()

时间:2023-03-31 17:59:19 vue.js

Vue性能提升的顺序-Vue文档在介绍数据绑定和响应时,特别标明通过了Object.freeze()方法的对象不能更新和响应。因此,我特意查看了Object.freeze()方法的具体含义。含义Object.freeze()方法用于冻结对象,禁止修改对象的属性(由于数组的本质也是对象,所以可以在数组上使用该方法)。MozillaMDN中是这样描述的:Anobjectcanbefrozen。无法再修改冻结的对象;当对象被冻结时,对象不能添加新的属性,不能删除已有的属性,也不能修改对象已有属性的可枚举性、可配置性和可写性。属性,并且不能修改现有属性的值。此外,对象冻结后,对象的原型将无法修改。方法的返回值是它的参数本身。需要注意的是,Object.freeze()在以下两点与const变量声明不同,不承担const的功能。const与Object.freeze()完全不同const的行为类似于let。它们之间的唯一区别是const定义了一个不能重新赋值的变量。用const声明的变量具有块级作用域,而不是用var声明的变量具有函数作用域。Object.freeze()将对象作为参数并返回相同的不可变对象。这意味着我们不能添加、删除或更改对象的任何属性。const和Object.freeze()不同,const是为了防止变量重新分配,而Object.freeze()是为了让对象不可变。下面的代码是正确的:Object.freeze()是一个“浅冻结”,下面的代码是有效的:实例的常规用法清楚地表明a的prop属性没有被改变,即使它被重新赋值。扩展“DeepFreeze”要完全冻结具有嵌套属性的对象,可以编写自己的库或使用现有的库来冻结对象,例如Deepfreeze或immutable-js//deepfreezefunction.functiondeepFreeze(obj){//返回在obj上定义的属性名称varpropNames=Object.getOwnPropertyNames(obj);//在冻结自身之前冻结属性propNames.forEach(function(name){varprop=obj[name];//如果prop是一个对象,则冻结它if(typeofprop=='object'&&prop!==null)deepFreeze(prop);});//freezeitself(no-opifalreadyfrozen)returnObject.freeze(obj);}复制代码实际上是一个简单的递归方法。但是涉及到一个非常重要的知识点Object.getOwnPropertyNames(obj),在写业务逻辑的时候很少用到。我们都知道JSObject中有原型链属性,所有非原型链属性都可以通过这个方法获取。使用Object.freeze()提升性能除了优化组件,我们还可以从Vue的依赖改造入手。在初始化时,Vue会修改数据的getter和setter。在现代浏览器中,这个过程其实是相当快的,但仍有优化的空间。Object.freeze()可以冻结一个对象。冻结后,对象不能再增加新的属性,不能修改其已有属性的值,不能删除已有属性,也不能修改对象已有属性的可枚举性。可配置性,可写性。此方法返回冻结的对象。当你将一个普通的JavaScript对象传递给Vue实例的数据选项时,Vue会遍历这个对象的所有属性,并使用Object.defineProperty将所有这些属性转换为getters/setters。这些getter/setter对用户来说是不可见的Visible,但在内部它们让Vue跟踪依赖关系,在访问和修改属性时通知更改。但是,当Vue遇到像Object.freeze()这样被设置为不可配置的对象属性时,它不会给对象添加settergetters等数据劫持方法。参考Vue源码Vueobserver源码性能提升效果对比在一个基于Vue的大表benchmark中,可以看到渲染1000x10的表时开启Object.freeze()前后重新渲染的对比。在此示例中,使用Object.freeze()比不使用它快4倍。为什么Object.freeze()的性能更好?不使用Object.freeze()的CPU开销是使用Object..freeze()的CPU开销对比可以看出,使用Object.freeze()后,观察者的开销降低了。Object.freeze()应用场景由于Object.freeze()会冻结对象,所以比较适合展示类的场景。如果您的数据属性需要更改,您可以将其替换为新的Object.freeze()对象。解冻Javascript对象修改ReactpropsReact生成的对象不能修改props,但在实践中,也有需要修改props的情况。如果直接修改,js代码会报错,因为props对象被冻结了,可以用Object.isFrozen()检测,结果为true。这意味着对象的属性是只读的。那么有没有办法解冻道具对象来修改呢?其实在javascript中,对象被冻结后,是没有办法解冻的,只能通过克隆一个具有相同属性的新对象,修改新对象的属性来实现。它可以是这样的:ES6:Object.assign({},frozenObject);lodash:_.assign({},frozenObject);复制代码让我们看看实际的代码:=Object.assign({},component.props)if(condictioin){if(condictioin.add)newProps.add=trueif(condictioin.del)newProps.del=true}newComponent.props=newPropsreturnnewComponent}复制代码锁objectmethodObject.preventExtensions()nonewpropertiesormethodscanbeaddedtotheproject对象不可扩展,即不能添加新的属性或方法,但是可以修改/删除Object.seal()同preventextension,plus防止现有的属性和方法被删除在上面的基础上,不能删除对象的属性,但是可以修改Object.freeze()同seal,pluspreventexistingpropertiesandmethodsfrombeingmodified在上面的基础上,对象的所有属性都是只读的,不能修改。以上三种方法分别使用Object.isExtensible()、Object.isSealed()、Object.isFrozen()来检测Object。freeze()阻止Vue实现响应式系统。当创建一个Vue实例时,它会将在其数据对象中可以找到的所有属性添加到Vue的响应式系统中。当这些属性的值发生变化时,视图将生成一个“响应”,即用新值更新匹配项。但如果使用Object.freeze(),这会阻止现有属性被修改,这也意味着React系统无法再跟踪更改。用法举例: