Выдает ошибку при попытке удалить неразрешенное свойство

Итак, я знаю, что вы можете предотвратить удаление свойства, установив для свойства configurable объекта значение false. Однако единственная обратная связь, которую вы получаете от этого действия удаления, — это логическое значение, которое показывает true или false. Есть ли способ немедленно выдать ошибку при удалении неразрешенного свойства?

const obj = {
  deleteMe: "Some text",
  dontDeleteMe: "Some other text"
};

Object.defineProperty(obj, 'dontDeleteMe', {
    value: "Some text",
    writable : true,
    enumerable : true,
    configurable : false
});


console.info(Object.keys(obj));
delete obj.deleteMe;
console.info(Object.keys(obj));
delete obj.dontDeleteMe;
console.info(Object.keys(obj));

Может помочь добавление прокси к вашему объекту: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ?

r3dst0rm 08.04.2019 13:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
76
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Если вы добавите use strict, возникнет ошибка:

'use strict';
const obj = {
  deleteMe: "Some text",
  dontDeleteMe: "Some other text"
};

Object.defineProperty(obj, 'dontDeleteMe', {
    value: "Some text",
    writable : true,
    enumerable : true,
    configurable : false
});


console.info(Object.keys(obj));
delete obj.deleteMe;
console.info(Object.keys(obj));
delete obj.dontDeleteMe;
console.info(Object.keys(obj));

С Прокси:

const obj = {
  deleteMe: "Some text",
  dontDeleteMe: "Some other text"
};

Object.defineProperty(obj, 'dontDeleteMe', {
    value: "Some text",
    writable : true,
    enumerable : true,
    configurable : false
});

const handler1 = {
  deleteProperty(target, prop) {
    delete target[prop];
    if (target[prop]) {
      throw new Error(`Invalid attempt to delete '${prop}' property`);
    }
    return true;
  }
};

const proxyObj = new Proxy(obj, handler1);
console.info(Object.keys(proxyObj));
delete proxyObj.deleteMe;
console.info(Object.keys(proxyObj));
delete proxyObj.dontDeleteMe;
console.info(Object.keys(proxyObj));

Рассматривая использование прокси-сервера, могу ли я просто использовать prop !== 'dontDeleteMe внутри обработчика удаления, чтобы запретить удаление, вместо того, чтобы также устанавливать для параметра configurable значение false? Или у этого подхода есть преимущество?

etarhan 08.04.2019 16:10

Они оба верны, вы можете использовать prop !== 'dontDeleteMe или установить configurable и выполнить динамический тест в обработчике, как я сделал, преимущество установки configurable заключается в том, чтобы избежать случайного удаления свойства, выполнив delete obj.dontDeleteMe вместо delete proxyObj.dontDeleteMe

Fraction 08.04.2019 16:35

Вы можете использовать "use strict"; с Object.defineProperty() или Object.freeze()


Подробности на странице МДН.

'use strict';
var obj = Object.freeze({name: 'Elsa', score: 157});
delete obj.score;  // TypeError

'use strict';
var obj = {};
Object.defineProperty(obj, 'foo', {value: 2, configurable: false});
delete obj.foo;  // TypeError

'use strict';
var frozenArray = Object.freeze([0, 1, 2]);
frozenArray.pop();  // TypeError

С вашим кодом:

"use strict";
const obj = {
  deleteMe: "Some text",
  dontDeleteMe: "Some other text"
};

Object.defineProperty(obj, 'dontDeleteMe', {
    value: "Some text",
    writable : true,
    enumerable : true,
    configurable : false
});


console.info(Object.keys(obj));
delete obj.deleteMe;
console.info(Object.keys(obj));
delete obj.dontDeleteMe;
console.info(Object.keys(obj));

Я бы предпочел не замораживать объект, он все еще должен быть редактируемым. Я просто хочу предотвратить удаление определенных свойств и выдать ошибку при попытке. Ваше предложение «использовать строгий» является хорошим, однако, если возможно, я хотел бы найти решение, не обязательно требующее строгого режима.

etarhan 08.04.2019 14:27

Если вы не хотите использовать "use strict" (по каким-либо причинам), это будет прокси-решение:

const obj = {
  deleteMe: "Some text",
  dontDeleteMe: "Some other text"
};

const deleteHandler = {
  deleteProperty(target, prop) {
    if (prop in target) {
      const deleted = delete target[prop];
      if (!deleted) {
        console.error(`deletion not allowed: ${prop}`);
      }
    }
  }
};

Object.defineProperty(obj, 'dontDeleteMe', {
  value: "Some text",
  writable: true,
  enumerable: true,
  configurable: false
});

const proxyObj = new Proxy(obj, deleteHandler);

console.info(Object.keys(proxyObj));
delete proxyObj.deleteMe;
console.info(Object.keys(proxyObj));
delete proxyObj.dontDeleteMe;
console.info(Object.keys(proxyObj));

Должен ли я по-прежнему явно устанавливать для configurable значение false, если я могу просто проверить имя свойства в deleteHandler?

etarhan 08.04.2019 16:24

Это зависит от вашего варианта использования. Безопаснее его сохранить. Но, конечно, вы можете настроить стираемость только внутри вашего deleteHandler.

Robert 08.04.2019 16:47

Другие вопросы по теме