Heim > Web-Frontend > Front-End-Fragen und Antworten > Was nützt das Einfrieren von Vue-Daten?

Was nützt das Einfrieren von Vue-Daten?

青灯夜游
Freigeben: 2023-01-12 18:54:10
Original
2114 Leute haben es durchsucht

In Vue wird die Methode „Object.freeze()“ zum Einfrieren von Daten verwendet, um das Objekt einzufrieren, und es ist verboten, die Eigenschaften des Objekts zu ändern (da Arrays von Natur aus auch Objekte sind, kann diese Methode für Arrays verwendet werden ). Nachdem ein Objekt eingefroren wurde, können vorhandene Attribute nicht gelöscht werden, die Aufzählbarkeit, Konfigurierbarkeit und Beschreibbarkeit der vorhandenen Attribute des Objekts können nicht geändert werden und die Werte vorhandener Attribute können nach dem Einfrieren eines Objekts nicht geändert werden Prototyp Es kann auch nicht geändert werden.

Was nützt das Einfrieren von Vue-Daten?

Die Betriebsumgebung dieses Tutorials: Windows7-System, Vue3-Version, DELL G3-Computer.

Bei der Einführung von Datenbindung und -antwort in der Vue-Dokumentation wird ausdrücklich darauf hingewiesen, dass Objekte, die die Methode Object.freeze() übergeben haben, nicht als Antwort aktualisiert werden können. Daher habe ich speziell die spezifische Bedeutung der Methode Object.freeze() überprüft.

Bedeutung

Die Methode Object.freeze() wird verwendet, um ein Objekt einzufrieren und die Änderung der Eigenschaften des Objekts zu verhindern (da Arrays im Wesentlichen Objekte sind, kann diese Methode für Arrays verwendet werden ). Es wird in Mozilla MDN wie folgt eingeführt: 数组本质也是对象,因此该方法可以对数组使用)。在 Mozilla MDN 中是如下介绍的:

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

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

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

需要注意的是以下两点

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

const和Object.freeze()完全不同

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

以下代码是正确的:

Was nützt das Einfrieren von Vue-Daten?

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

Was nützt das Einfrieren von Vue-Daten?

实例

常规用法

Was nützt das Einfrieren von Vue-Daten?

明显看到,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);
}
Nach dem Login kopieren

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

利用Object.freeze()提升性能

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

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

当你把一个普通的 JavaScript 对象传给 Vue 实例的 dataSie können ein Objekt einfrieren. Ein eingefrorenes Objekt kann nicht mehr geändert werden; wenn ein Objekt eingefroren ist, können dem Objekt keine neuen Attribute hinzugefügt werden, vorhandene Attribute können nicht gelöscht werden und die Aufzählbarkeit, Konfigurierbarkeit und Beschreibbarkeit der vorhandenen Attribute des Objekts können nicht geändert werden und die Unfähigkeit, den Wert bestehender Eigenschaften zu ändern. Darüber hinaus kann der Prototyp eines Objekts nach dem Einfrieren nicht mehr geändert werden

🎜🎜Der Rückgabewert dieser Methode ist ihr Parameter selbst. 🎜🎜Es ist wichtig, die folgenden zwei Punkte zu beachten: 1. Object.freeze() unterscheidet sich von const-Variablendeklarationen und übernimmt nicht die Funktionen von const. 🎜🎜const unterscheidet sich völlig von Object.freeze() 🎜
  • const verhält sich wie let. Der einzige Unterschied zwischen ihnen besteht darin, dass const eine Variable definiert, die nicht neu zugewiesen werden kann. Mit const deklarierte Variablen haben einen Blockbereich, keinen Funktionsbereich wie mit var deklarierte Variablen.
  • Object.freeze() akzeptiert ein Objekt als Parameter und gibt ein identisches unveränderliches Objekt zurück. Das bedeutet, dass wir keine Eigenschaften des Objekts hinzufügen, löschen oder ändern können.
  • Const unterscheidet sich von Object.freeze(). Const verhindert die Neuzuweisung von Variablen, während Object.freeze() das Objekt unveränderlich macht.
🎜Der folgende Code ist korrekt: 🎜🎜Was nützt das Einfrieren von Vue-Daten?🎜🎜2. Object.freeze() ist „flaches Einfrieren“, der folgende Code ist wirksam:🎜🎜Was nützt das Einfrieren von Vue-Daten?🎜

🎜Beispiel🎜🎜🎜Allgemeine Verwendung 🎜🎜Was nützt das Einfrieren von Vue-Daten?🎜🎜Offensichtlich Sehen Sie, das Prop-Attribut von a wurde nicht geändert, auch wenn es neu zugewiesen wurde. 🎜

🎜Extensions🎜🎜🎜"Deep Freeze"🎜🎜Um Objekte mit verschachtelten Eigenschaften vollständig einzufrieren, können Sie Ihre eigene Bibliothek schreiben oder eine vorhandene Bibliothek zum Einfrieren von Objekten verwenden, z. B. < a target="_blank" href="https://www.php.cn/link/4a5b6a06ed76e8740ccc925fa9532ef2" title="https://github.com/substack/deep-freeze" ref="nofollow noopener noreferrer"> Deepfreeze🎜 oder
ES6: Object.assign({}, frozenObject);
lodash: _.assign({}, frozenObject);
Nach dem Login kopieren
Nach dem Login kopieren

🎜 ist eigentlich eine einfache rekursive Methode. Beim Schreiben der Geschäftslogik Object.getOwnPropertyNames(obj) handelt es sich jedoch um einen sehr wichtigen, aber selten genutzten Wissenspunkt. Wir alle wissen, dass es in JS Object Prototypketteneigenschaften gibt und alle Nicht-Prototypketteneigenschaften über diese Methode abgerufen werden können. 🎜

🎜Verwenden Sie Object.freeze(), um die Leistung zu verbessern🎜🎜🎜Zusätzlich zur Komponentenoptimierung können wir auch mit der Vue-Abhängigkeitstransformation beginnen. Während der Initialisierung führt Vue Getter- und Setter-Transformationen an Daten durch. In modernen Browsern ist dieser Prozess eigentlich recht schnell, es gibt jedoch noch Raum für Optimierung. 🎜🎜Object.freeze() kann ein Objekt einfrieren. Nach dem Einfrieren können dem Objekt keine neuen Attribute hinzugefügt werden, die Werte vorhandener Attribute können nicht geändert werden, vorhandene Attribute können nicht gelöscht werden Das Objekt kann nicht geändert werden. Aufzählbarkeit, Konfigurierbarkeit und Beschreibbarkeit vorhandener Eigenschaften. Diese Methode gibt das eingefrorene Objekt zurück. 🎜🎜Wenn Sie ein normales JavaScript-Objekt an die Option data der Vue-Instanz übergeben, durchläuft Vue alle Eigenschaften des Objekts und verwendet 🎜Object.defineProperty🎜, um alle diese Eigenschaften in Getter/Setter umzuwandeln Diese Getter/Setter sind für den Benutzer unsichtbar, aber intern ermöglichen sie Vue, Abhängigkeiten zu verfolgen und Änderungen zu benachrichtigen, wenn auf Eigenschaften zugegriffen und diese geändert werden. 🎜

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

Vue observer 源码

Was nützt das Einfrieren von Vue-Daten?

性能提升效果对比

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

big table benchmark

Was nützt das Einfrieren von Vue-Daten?

开启优化之前

Was nützt das Einfrieren von Vue-Daten?

开启优化之后

Was nützt das Einfrieren von Vue-Daten?

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

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

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

Was nützt das Einfrieren von Vue-Daten?

使用 Object.freeze()的CPU开销

Was nützt das Einfrieren von Vue-Daten?

对比可以看出,使用了 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);
Nach dem Login kopieren
Nach dem Login kopieren

来看实际代码:

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
}
Nach dem Login kopieren

锁定对象的方法

  • 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>
Nach dem Login kopieren

运行后:

Was nützt das Einfrieren von Vue-Daten?

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

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

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

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>
Nach dem Login kopieren
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 }
        ]);
    }
})
Nach dem Login kopieren

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

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

Das obige ist der detaillierte Inhalt vonWas nützt das Einfrieren von Vue-Daten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
vue
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Empfehlungen
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage