# Объект для чтения

Такой же принцип, как и для примитива.

Пока я готовила пример, я обнаружила одну любопытную особенность. Даже с Proxy, запрещающим по идее любые изменения, если добавить новое поле в компоненте таким образом

this.$set(this.obj, 'newField', 'Got ya!')

То это сработает, новое поле добавится. Если новое поле попытаться добавить из компонента классическим способом, то есть

this.obj.newField = 'Nah';

То вот так не сработает. А через $set работает. Изменение существующих полей даже через $set не проходит, так что думаю уровень защищенности достаточный, но про такую особенность стоит знать.

# Класс


 




 








 
 






class ReadonlyObject {
  _obj = {
    field: 'string',
    field2: 'anotherString'
  }

  get obj() {
    return new Proxy(this._obj, {
      set() {
        throw new Error('This property is read-only')
      }
    })
  }

  changeField() {
    this._obj.field = 'number';
    this._obj.field2 = 'anotherNumber';
  }
}

const instance = new ReadonlyObject();

export default instance;

# Компонент


























 








<template>
  <div class="component-block">
    <span class="name">ReadonlyObjectOne</span>

    <div><b>Значение obj:</b> {{ obj }}</div>
    <button @click="changeField">Изменить поля через метод</button><br />
    <button @click="tryToChange">Изменить поля через компонент</button><br />
    <div>{{ error }}</div>
  </div>
</template>

<script>
import ReadonlyObject from '@example-services/ReadonlyObject';

export default {
  data() {
    return {
      obj: ReadonlyObject.obj,
      changeField: ReadonlyObject.changeField.bind(ReadonlyObject),
      error: null,
    };
  },
  methods: {
    tryToChange() {
      try {
        this.obj.field = 'fromComponent'; // Ошибка!
      } catch(e) {
        this.error = e;
      }
    }
  }
}
</script>

# Результат

ReadonlyObjectOne
Значение obj: { "field": "string", "field2": "anotherString" }


ReadonlyObjectTwo
Значение obj: { "field": "string", "field2": "anotherString" }
Обновлено: 12/12/2022, 3:53:53 PM