Как использовать Object.freeze() в Javascript

JavaScript
Как использовать Object.freeze() в Javascript

Object.freeze()

Метод Object.freeze() замораживает объект. Замороженный объект больше не может быть изменен; когда объект заморожен, к объекту нельзя добавить новые свойства, существующие свойства нельзя удалить, а перечисляемость, конфигурируемость и возможность записи существующих свойств объекта нельзя изменить. и не может изменить значение существующего свойства. Кроме того, после замораживания объекта прототип объекта не может быть изменен. замораживание() возвращает тот же объект, который был передан в

Применение

const objectExample = {
  prop1: 20,
  prop2: "羊先生"
};

// 默认情况下,我们可以根据需要修改对象的属性
objectExample.prop1 = 100;
console.log(objectExample.prop1)

// 冻结对象
Object.freeze(objectExample);

objectExample.prop2 = "Alice" // 如果在严格模式会抛出失败,在非严格模式下只会抛出异常

console.log(objectExample.prop2);

результат

нестрогий режим

image.png
image.png

Добавить строгий режим

"use strict";
image.png
image.png

Выдает исключение, указывающее, что свойство доступно только для чтения

морозильник

Обратите внимание, что если замораживаемый объект имеет свойства с объектами в качестве значений, эти объекты можно изменить.

const theObject = {
  x: 1,
  z: 2,
  y: {
    a: "Hello",
    b: "羊先生"
  }
}

Object.freeze(theObject);

theObject.x = 100
console.log(theObject.x);

theObject.y.a = 'vipbic';
console.log(theObject.y.a);
результат
image.png
image.png

Обнаружено, что первый слой объекта заморожен, а второй слой не заморожен, значит, мы реализовали только"неглубокая заморозка"Чтобы сделать объект неизменным, заморозив все его свойства (включая те, которые хранят другие объекты в качестве значений), мы должны сделать"морозильник"— даже использование рекурсии для замораживания дочерних объектов перед замораживанием родительских объектов.

рекурсивная заморозка

const theObject = {
  x: 1,
  z: 2,
  y: {
    a: "Hello",
    b: "羊先生"
  }
}

const deepFreeze = (obj) => {

  const propNames = Object.getOwnPropertyNames(obj)

  for (const name of propNames) {
    const value = obj[name];

    if (value && typeof value === "object") { 
      deepFreeze(value);
    }
  }

  return Object.freeze(obj);
}

deepFreeze(theObject);
theObject.y.a = 100;
console.log(theObject.y.a );
результат
image.png
image.png

Использование Object.freeze в Vue

В vue2.0, когда вы передаете обычный объект JavaScript в параметр данных экземпляра Vue, Vue будет проходить по всем свойствам этого объекта и использовать Object.defineProperty для преобразования всех этих свойств в геттеры/сеттеры, эти геттеры/установщики невидимы. пользователю, но внутри они позволяют Vue отслеживать зависимости, уведомляя об изменениях при доступе к свойствам и их изменении.

Иногда в практических приложениях мы используем его только для хранения объекта или массива и не требуем, чтобы он реагировал на соответствующее представление, но в этом процессе Vue по-прежнему будет использовать object.defineProperty для мониторинга массива, что является производительностью. Поэтому мы можем использовать Object.freeze для замораживания данных.

<h4 v-for="(item,idx) in items" :key="idx">{{ item.text }}</h4>
data() {
    let data =  Object.freeze([{text:'羊先生'},{text:'ipbic'}])
    return {
       msg: '',
       items:data
    }
},
mounted() {

    this.items[0].text = '分享快乐'; // 界面不会更新

    this.items = [{ text: 'itnavs' },{ text: '分享快乐' }]; // 界面会更新

    this.items = Object.freeze([{ text: 'itnavs' },{ text: '分享快乐' }]); // 界面会更新
},

Если у вас есть огромный массив или объект, и вы уверены, что данные не будут изменены, использование Object.freeze() может дать вам огромный прирост производительности. В моей реальной разработке это улучшение примерно в 5-10 раз, и множитель увеличивается с объемом данных.

использоватьObject.freezeЧтобы избежать растраты такого рода ресурсов, не смотрите на него как на мелочь, а игнорируйте его.