>  기사  >  웹 프론트엔드  >  Vue 데이터 동결의 용도는 무엇입니까?

Vue 데이터 동결의 용도는 무엇입니까?

青灯夜游
青灯夜游원래의
2023-01-12 18:54:101982검색

vue에서는 데이터 고정 "Object.freeze()" 메소드를 사용하여 객체를 고정하고 객체의 속성을 수정하는 것은 금지되어 있습니다(배열도 본질적으로 객체이기 때문에 이 메소드는 배열에 사용할 수 있습니다) ). 객체가 고정된 후에는 기존 속성을 삭제할 수 없으며 객체의 기존 속성에 대한 열거 가능성, 구성 가능성 및 쓰기 가능성을 수정할 수 없으며 기존 속성의 값도 수정할 수 없습니다. 프로토타입 역시 수정할 수 없습니다.

Vue 데이터 동결의 용도는 무엇입니까?

이 튜토리얼의 운영 환경: windows7 시스템, vue3 버전, DELL G3 컴퓨터.

Vue 문서에 데이터 바인딩 및 응답을 소개할 때 Object.freeze() 메서드를 전달한 객체는 응답으로 업데이트될 수 없다는 점에 특히 명시되어 있습니다. 그래서 Object.freeze() 메소드의 구체적인 의미를 구체적으로 확인해 보았습니다.

의미

Object.freeze() 메서드는 객체를 고정하고 객체 속성의 수정을 금지하는 데 사용됩니다(배열은 본질적으로 객체이므로, 이 메서드는 배열에 사용할 수 있습니다) ). Mozilla MDN에는 다음과 같이 소개되어 있습니다. 数组本质也是对象,因此该方法可以对数组使用)。在 Mozilla MDN 中是如下介绍的:

可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,

不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改

该方法的返回值是其参数本身。

需要注意的是以下两点

1、Object.freeze() 和 const 变量声明不同,也不承担 const 的功能。

const和Object.freeze()完全不同

  • const的行为像 let。它们唯一的区别是, const定义了一个无法重新分配的变量。 通过 const声明的变量是具有块级作用域的,而不是像 var声明的变量具有函数作用域。
  • Object.freeze()接受一个对象作为参数,并返回一个相同的不可变的对象。这就意味着我们不能添加,删除或更改对象的任何属性。
  • const和Object.freeze()并不同,const是防止变量重新分配,而Object.freeze()是使对象具有不可变性。

以下代码是正确的:

Vue 데이터 동결의 용도는 무엇입니까?

2、Object.freeze() 是“浅冻结”,以下代码是生效的:

Vue 데이터 동결의 용도는 무엇입니까?

实例

常规用法

Vue 데이터 동결의 용도는 무엇입니까?

明显看到,a 的 prop 属性未被改变,即使重新赋值了。

延伸

"深冻结"

要完全冻结具有嵌套属性的对象,您可以编写自己的库或使用已有的库来冻结对象,如Deepfreezeimmutable-js

// 深冻结函数.
function deepFreeze(obj) {

  // 取回定义在obj上的属性名
  var propNames = Object.getOwnPropertyNames(obj);

  // 在冻结自身之前冻结属性
  propNames.forEach(function(name) {
    var prop = obj[name];

    // 如果prop是个对象,冻结它
    if (typeof prop == 'object' && prop !== null)
      deepFreeze(prop);
  });

  // 冻结自身(no-op if already frozen)
  return Object.freeze(obj);
}

其实就是个简单的递归方法。但是涉及到一个很重要,但是在写业务逻辑的时候很少用的知识点 Object.getOwnPropertyNames(obj) 。我们都知道在 JS 的 Object 中存在原型链属性,通过这个方法可以获取所有的非原型链属性。

利用Object.freeze()提升性能

除了组件上的优化,我们还可以对vue的依赖改造入手。初始化时,vue会对data做getter、setter改造,在现代浏览器里,这个过程实际上挺快的,但仍然有优化空间。

Object.freeze() 可以冻结一个对象,冻结之后不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。该方法返回被冻结的对象。

当你把一个普通的 JavaScript 对象传给 Vue 实例的  data객체를 고정할 수 있습니다. 고정된 개체는 더 이상 수정할 수 없습니다. 개체가 고정된 경우 새 특성을 개체에 추가할 수 없고 기존 특성을 삭제할 수 없으며 개체의 기존 특성에 대한 열거 가능성, 구성 가능성 및 쓰기 가능성을 수정할 수 없습니다. , 기존 속성의 값을 수정할 수 없습니다. 또한 객체의 프로토타입은 고정한 후에 수정할 수 없습니다.

🎜🎜이 메서드의 반환 값은 매개 변수 자체입니다. 🎜🎜다음 두 가지 사항에 유의하는 것이 중요합니다🎜🎜1. Object.freeze()는 const 변수 선언과 다르며 const의 기능을 가정하지 않습니다. 🎜🎜const는 Object.freeze()와 완전히 다릅니다. 🎜
  • const는 let처럼 동작합니다. 둘 사이의 유일한 차이점은 const가 재할당할 수 없는 변수를 정의한다는 것입니다. const로 선언된 변수에는 블록 범위가 있지만 var로 선언된 변수와 같은 함수 범위는 없습니다.
  • Object.freeze()는 객체를 매개변수로 받아들이고 동일한 불변 객체를 반환합니다. 즉, 개체의 속성을 추가, 삭제 또는 변경할 수 없습니다.
  • Const는 Object.freeze()와 다릅니다. const는 변수가 재할당되는 것을 방지하는 반면 Object.freeze()는 객체를 변경할 수 없게 만듭니다.
🎜다음 코드는 정확합니다: 🎜🎜Vue 데이터 동결의 용도는 무엇입니까?🎜🎜2. Object.freeze()는 "얕은 동결"이며 다음 코드가 효과적입니다:🎜🎜Vue 데이터 동결의 용도는 무엇입니까?🎜

🎜예🎜🎜🎜일반 사용법 🎜🎜Vue 데이터 동결의 용도는 무엇입니까?🎜🎜분명한 재할당되더라도 a의 prop 속성은 변경되지 않았습니다. 🎜

🎜Extensions🎜🎜🎜"Deep Freeze"🎜🎜중첩된 속성이 있는 개체를 완전히 고정하려면 고유한 라이브러리를 작성하거나 기존 라이브러리를 사용하여 Deepfreeze🎜 또는 immutable-js🎜🎜
ES6: Object.assign({}, frozenObject);
lodash: _.assign({}, frozenObject);
🎜는 실제로 간단한 재귀 방법입니다. 그러나 이는 비즈니스 논리 Object.getOwnPropertyNames(obj)를 작성할 때 매우 중요하지만 거의 사용되지 않는 지식 포인트를 포함합니다. 우리 모두는 JS 객체에 프로토타입 체인 속성이 있다는 것을 알고 있으며, 프로토타입이 아닌 모든 체인 속성은 이 방법을 통해 얻을 수 있습니다. 🎜

🎜Object.freeze()를 사용하여 성능 향상🎜🎜🎜구성 요소 최적화 외에도 vue 종속성 변환으로 시작할 수도 있습니다. 초기화 중에 Vue는 데이터에 대해 getter 및 setter 변환을 수행합니다. 최신 브라우저에서는 이 프로세스가 실제로 매우 빠르지만 여전히 최적화할 여지가 있습니다. 🎜🎜Object.freeze()는 객체를 고정할 수 있으며, 고정 후에는 새 속성을 객체에 추가할 수 없고, 기존 속성의 값을 수정할 수 없으며, 기존 속성을 삭제할 수 없습니다. 개체는 기존 속성의 열거 가능성, 구성 가능성 및 쓰기 가능성을 수정할 수 없습니다. 이 메서드는 고정된 개체를 반환합니다. 🎜🎜일반 JavaScript 객체를 Vue 인스턴스의 data 옵션에 전달하면 Vue는 객체의 모든 속성을 탐색하고 🎜Object.defineProperty🎜를 사용하여 이러한 모든 속성을 getter/setter로 변환합니다. , 이러한 getter/setter는 사용자에게 보이지 않지만 내부적으로는 Vue가 종속성을 추적하고 속성에 액세스하고 수정될 때 변경 사항을 알릴 수 있습니다. 🎜

但 Vue 在遇到像 Object.freeze() 这样被设置为不可配置之后的对象属性时,不会为对象加上 setter getter 等数据劫持的方法。参考 Vue 源码

Vue observer 源码

Vue 데이터 동결의 용도는 무엇입니까?

性能提升效果对比

在基于 Vue 的一个 big table benchmark 里,可以看到在渲染一个一个 1000 x 10 的表格的时候,开启Object.freeze() 前后重新渲染的对比。

big table benchmark

Vue 데이터 동결의 용도는 무엇입니까?

开启优化之前

Vue 데이터 동결의 용도는 무엇입니까?

开启优化之后

Vue 데이터 동결의 용도는 무엇입니까?

在这个例子里,使用了 Object.freeze()比不使用快了 4 倍

为什么Object.freeze() 的性能会更好

不使用Object.freeze() 的CPU开销

Vue 데이터 동결의 용도는 무엇입니까?

使用 Object.freeze()的CPU开销

Vue 데이터 동결의 용도는 무엇입니까?

对比可以看出,使用了 Object.freeze() 之后,减少了 observer 的开销。

Object.freeze()应用场景

由于 Object.freeze()会把对象冻结,所以比较适合展示类的场景,如果你的数据属性需要改变,可以重新替换成一个新的 Object.freeze()的对象。

Javascript对象解冻

修改 React props React生成的对象是不能修改props的, 但实践中遇到需要修改props的情况. 如果直接修改, js代码将报错, 原因是props对象被冻结了, 可以用Object.isFrozen()来检测, 其结果是true. 说明该对象的属性是只读的.

那么, 有方法将props对象解冻, 从而进行修改吗?

事实上, 在javascript中, 对象冻结后, 没有办法再解冻, 只能通过克隆一个具有相同属性的新对象, 通过修改新对象的属性来达到目的.

可以这样:

ES6: Object.assign({}, frozenObject);
lodash: _.assign({}, frozenObject);

来看实际代码:

function modifyProps(component) {
  let condictioin = this.props.condictioin,
    newComponent = Object.assign({}, component),
    newProps = Object.assign({}, component.props)
  
  if (condictioin) {
    if (condictioin.add) newProps.add = true
    if (condictioin.del) newProps.del = true
  }
  newComponent.props = newProps
  
  return newComponent
}

锁定对象的方法

  • Object.preventExtensions()

no new properties or methods can be added to the project 对象不可扩展, 即不可以新增属性或方法, 但可以修改/删除

  • Object.seal()

same as prevent extension, plus prevents existing properties and methods from being deleted 在上面的基础上,对象属性不可删除, 但可以修改

  • Object.freeze()

same as seal, plus prevent existing properties and methods from being modified 在上面的基础上,对象所有属性只读, 不可修改

以上三个方法分别可用Object.isExtensible(), Object.isSealed(), Object.isFrozen()来检测

Object.freeze( ) 阻止Vue无法实现 响应式系统

当一个 Vue 实例被创建时,它向 Vue 的响应式系统中加入了其 data 对象中能找到的所有的属性。当这些属性的值发生改变时,视图将会产生“响应”,即匹配更新为新的值。但是如果使用 Object.freeze(),这会阻止修改现有的属性,也意味着响应系统无法再追踪变化。

具体使用办法举例:

<template>
  <div>
     <p>freeze后会改变吗
        {{obj.foo}}
     </p>
      <!-- 两个都不能修改??为什么?第二个理论上应该是可以修改的-->
      <button @click="change">点我确认</button>
  </div>
</template>

<script>
var obj = {
  foo: &#39;不会变&#39;
}
Object.freeze(obj)
export default {
  name: &#39;index&#39;,
  data () {
    return {
      obj: obj
    }
  },
  methods: {
    change () {
      this.obj.foo = &#39;改变&#39;
    }
  }
}
</script>

运行后:

Vue 데이터 동결의 용도는 무엇입니까?

从报错可以看出只读属性foo不能进行修改,Object.freeze()冻结的是值,你仍然可以将变量的引用替换掉,将上述代码更改为:

<button @click="change">点我确认</button>

change () {
      this.obj = {
        foo: &#39;会改变&#39;
      }
    }

Object.freeze()是ES5新增的特性,可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。防止对象被修改。 如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升。

实践心得和技巧

Object.freeze()是ES5新增的特性,可以冻结一个对象,防止对象被修改。

vue 1.0.18+对其提供了支持,对于data或vuex里使用freeze冻结了的对象,vue不会做getter和setter的转换。

如果你有一个巨大的数组或Object,并且确信数据不会修改,使用Object.freeze()可以让性能大幅提升。在我的实际开发中,这种提升大约有5~10倍,倍数随着数据量递增。

并且,Object.freeze()冻结的是值,你仍然可以将变量的引用替换掉。举个例子:

<p v-for="item in list">{{ item.value }}</p>
new Vue({
    data: {
        // vue不会对list里的object做getter、setter绑定
        list: Object.freeze([
            { value: 1 },
            { value: 2 }
        ])
    },
    created () {
        // 界面不会有响应
        this.list[0].value = 100;

        // 下面两种做法,界面都会响应
        this.list = [
            { value: 100 },
            { value: 200 }
        ];
        this.list = Object.freeze([
            { value: 100 },
            { value: 200 }
        ]);
    }
})

vue的文档没有写上这个特性,但这是个非常实用的做法,对于纯展示的大数据,都可以使用Object.freeze提升性能。

(学习视频分享:vuejs入门教程编程基础视频

위 내용은 Vue 데이터 동결의 용도는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.