Итак, я знаю, что вы можете предотвратить удаление свойства, установив для свойства 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));
Если вы добавите 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? Или у этого подхода есть преимущество?
Они оба верны, вы можете использовать prop !== 'dontDeleteMe
или установить configurable и выполнить динамический тест в обработчике, как я сделал, преимущество установки configurable заключается в том, чтобы избежать случайного удаления свойства, выполнив delete obj.dontDeleteMe
вместо delete proxyObj.dontDeleteMe
Вы можете использовать "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));
Я бы предпочел не замораживать объект, он все еще должен быть редактируемым. Я просто хочу предотвратить удаление определенных свойств и выдать ошибку при попытке. Ваше предложение «использовать строгий» является хорошим, однако, если возможно, я хотел бы найти решение, не обязательно требующее строгого режима.
Если вы не хотите использовать "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?
Это зависит от вашего варианта использования. Безопаснее его сохранить. Но, конечно, вы можете настроить стираемость только внутри вашего deleteHandler.
Может помочь добавление прокси к вашему объекту: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ?