ホームページ > ウェブフロントエンド > フロントエンドQ&A > Vue データのフリーズは何に役立ちますか?

Vue データのフリーズは何に役立ちますか?

青灯夜游
リリース: 2023-01-12 18:54:10
オリジナル
2058 人が閲覧しました

vue では、データを凍結する「Object.freeze()」メソッドを使用してオブジェクトを凍結します。オブジェクトのプロパティを変更することは禁止されています (配列も本質的にはオブジェクトであるため、このメソッドは変更できます)配列で使用できます)。オブジェクトをフリーズした後は、既存の属性を削除したり、オブジェクトの既存の属性の列挙可能性、構成可能性、書き込み可能性を変更したり、既存の属性の値を変更したりすることはできません。また、オブジェクトをフリーズした後は、オブジェクトのプロトタイプも変更できません。

Vue データのフリーズは何に役立ちますか?

#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。

Vue のドキュメントでデータ バインディングと応答を紹介する際、Object.freeze() メソッドを渡すオブジェクトは更新に応答できないことに特に注意してください。そこで、Object.freeze()メソッドの具体的な意味を具体的に確認してみました。

意味

Object.freeze() メソッドはオブジェクトをフリーズするために使用され、オブジェクトのプロパティを変更することは禁止されています (

array であるため)も本質的にはオブジェクトです ので、このメソッドは配列に対して使用できます)。 Mozilla MDN では、次のように導入されています:

オブジェクトをフリーズできます。凍結されたオブジェクトは変更できなくなります。オブジェクトが凍結された場合、新しい属性をオブジェクトに追加できず、

は既存の属性を削除できず、オブジェクトの既存の属性の列挙可能性を変更できません。 、および既存のプロパティの値を変更できないこと。さらに、オブジェクトのプロトタイプは、フリーズした後は変更できません。

このメソッドの戻り値はパラメータそのものです。

次の 2 点に注意してください

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 データのフリーズは何に役立ちますか?

明らかに、プロップ属性は再割り当てされても変更されません。

拡張機能

「ディープ フリーズ」

ネストされたプロパティを持つオブジェクトを完全にフリーズするには、独自のライブラリを作成するか、既存のライブラリを使用して

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.freeze() を使用するパフォーマンスを向上させる

コンポーネントの最適化に加えて、vue の依存関係の変換から始めることもできます。初期化中に、Vue はデータに対してゲッターとセッターの変換を実行します。最新のブラウザでは、このプロセスは実際には非常に高速ですが、まだ最適化の余地があります。

Object.freeze() オブジェクトをフリーズできます。フリーズ後は、オブジェクトに新しい属性を追加したり、既存の属性の値を変更したり、既存の属性を削除したりすることはできません。オブジェクトの既存の属性の列挙可能性、構成可能性、および書き込み可能性を変更することはできません。このメソッドは、凍結されたオブジェクトを返します。

通常の JavaScript オブジェクトを Vue インスタンスの

data オプションに渡すと、Vue はオブジェクトのすべてのプロパティを反復処理し、Object.defineProperty を使用してこれらのプロパティを定義すると、すべてゲッター/セッターに変換されます。これらのゲッター/セッターはユーザーには見えませんが、内部的には、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 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
vue
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート