Как предотвратить изменение объекта в Javascript и сделать его недоступным в консоли

Есть много способов заблокировать объект в соответствии с вашими потребностями. Object Объект (несмотря на избыточность), имеет несколько полезных функций, которые позволят вам блокировать объекты.

  • Object.freeze
  • Object.seal
  • Object.preventExtensions

Для всех примеров в этом посте мы будем использовать следующий объект:

var myBankAccount = {
user: {
fullname : "Bruce wayne",
age: 26,
occupation: {
day: "Philanthropist billionaire",
night: "I'm Batman"
}
},
multipleAccounts: true,
accounts : [
{
money: (9999999999999999),
currency : "EUR"
},
{
money: (9999999999999999),
currency : "USD"
}
]
};

Object.freeze

Метод Freeze замораживает объект (спасибо капитану очевидно).

Этот метод предотвращает добавление новых свойств, предотвращает удаление существующих свойств и предотвращает изменение существующих свойств (или их перечислимость, конфигурируемость или возможность записи). По сути, объект сделан неизменным. Метод возвращает замороженный объект.

// Add a property before being frozen
myBankAccount.bankName = "Gotham Merchant Bank";
// Shows the value in the object as the property
// was created before the object has been frozen
console.log(myBankAccount.bankName);
// Freeze the object
Object.freeze(myBankAccount);
/**
* Now the object cannot be modified, deleted written
*/
myBankAccount.flushMethod = function(){
SendAllMoneyToJokerAccount();
};
// Will be neither deleted !
delete myBankAccount.bankName;
// Throws error, method doesn't exist.
myBankAccount.flushMethod();

Обратите внимание, что вы замораживаете только объект в качестве первого параметра. Если значение замороженного объекта является объектом, оно все еще может быть изменено, если вы не замораживаете их тоже. Если вы попытаетесь изменить myBankAccount.user , вы сможете добавить свойства внутри этого объекта.

// Freeze object
Object.freeze(myBankAccount);
// The user property is an object, and you didn't freeze it Too
// to solve use Object.freeze(myBankAccount.user)
myBankAccount.user.flushMethod = function(){
SendAllMoneyToJokerAccount();
};
// Money succesfully transfered :(
// You disappoint Batman
myBankAccount.user.flushMethod();

Object.preventExtensions

Метод protectExtensions предотвращает добавление новых свойств к объекту (то есть предотвращает будущие расширения объекта).

// Add property before being nonExtensible
myBankAccount.newValue = 12;
// Disallow new properties to the bank account
Object.preventExtensions(myBankAccount);
// Silently ignored or TypeError
myBankAccount.flushAccount = function(){
sendMoneyToJokerAccount();
};
console.log(myBankAccount.newValue);// Output :12
// Method doesn't exist
myBankAccount.flushAccount();

Object.seal

Метод Seal запечатывает объект, предотвращая добавление к нему новых свойств и помечая все существующие свойства как неконфигурируемые. Значения существующих свойств могут все еще быть изменены, пока они доступны для записи.

// Seal object
Object.seal(myBankAccount);
// Changing property values on a sealed object still works.
myBankAccount.multipleAccounts = false;
// But you can't convert data properties to accessors, or vice versa.
Object.defineProperty(myBankAccount, 'foo', { get: function() { return 'hey'; } }); // throws a TypeError
delete myBankAccount.user; // throws a TypeError
myBankAccount.newPropertyToAdd = 'qwe'; // throws a TypeError

Быстрое сравнение и заметки

функция
Объект сделан нерасширяемым
настраиваемый имеет значение false для каждого свойства
Object.preventExtensionsданет
Object.sealдада
Object.freezeдада
  • Субобъекты замороженного объекта являются изменяемыми, если вы их не заморозите.
  • Прототип цепи с использованием Object.seal остается нетронутым Тем не менее __proto__ собственность также опечатана.
  • Свойства все еще могут быть добавлены к прототипу объекта. Тем не менее, призывая preventExtensions на объекте также будет предотвращать расширения на его __proto__ имущество.

Переменная Object имеет полезный метод, чтобы проверить, использовалась ли какая-либо из предыдущих функций для объекта:

  • Object.isFrozen(myObj),
  • Object.isSealed(myObj),
  • Object.isExtensible(myObj),

Если вы не работаете со строгим режимом в вашем коде ('use strict';) в консоли не будет выдано никаких ошибок, так как все будет игнорироваться. Однако в строгом режиме вы получите Type Errors если вы попытаетесь выполнить задачу, добавив свойство в нерасширяемый объект и т. д.

Запретить доступ к переменной в консоли

Если вы боитесь, что кто-то может проверить ваш код и изменить что-то в консоли, просто поместите ваш код в анонимную функцию. Это предотвратит появление в консоли, поэтому другие разработчики не смогут получить доступ к коду таким образом.

Проанализируйте следующий код:


var allow_transaction = false;
var MySuperBankObject = {
person: "Bruce",
account: 123123,
money: (9999.99),
sendMoneyToAccount : function(idAccount,amount){
if(amount <= this.money){
allow_transaction = true;
TransferToAccount(this.account,idAccount,amount);
}else{
throw new Error("Too much money. You don't have all that money :(.");
}
}
};
function TransferToAccount(source_account,target_account,amount){
if(!allow_transaction){
throw new Error("The transaction needs to be verified");
}
console.log(amount + " Dollars succesfully transfered to " + target_account + " account from "+ source_account);
}
// Onclick, do transaction
document.getElementById("transfer").addEventListener("click",function(){
// get required info
var amount = document.getElementById("amount").value;
var accountTarget = document.getElementById("account").value;
// Do transaction
MySuperBankObject.sendMoneyToAccount(parseInt(accountTarget),parseFloat(amount));
},false);

Если вы включите этот код в свой документ, и кто-то решит прочитать код этих файлов, он может найти и выполнить следующее в консоли, потому что объект MySuperBankObject представлен глобально:

Запретить прием переменной в консоли

А никто этого не хочет? Чтобы предотвратить это (хотя код может быть виден в браузере, его нельзя изменить), оберните предыдущий код в анонимную функцию:

(function(){
/**
* All the code that needs to be unexposed in the console here.
*/
})(); // Send parameters inside the function if you need to

Теперь оберните предыдущий внутри анонимной функции:


(function(){
var allow_transaction = false;
var MySuperBankObject = {
person: "Bruce",
account: 123123,
....
....
})();

Полезно не? Если разработчик попытается получить mySuperBankObject в консоли, он столкнется с этим:

не определена консоль

Код будет работать как положено, но переменные больше не отображаются в консоли. Обратите внимание, что код все еще читается разработчиком, хотя не может быть легко изменено он все еще изменяется, если у вашего кода есть слабые места (геттеры и сеттеры неправильно настроены, т.е. глупая глобальная функция как getMySuperBankObject ...) и с достаточными знаниями. Сократите код, чтобы уменьшить читабельность.

Наконец, пожалуйста, не обрабатывайте банковский счет с каким-либо кодом, подобным указанному в этом сообщении, спасибо!.

Повеселись

Ссылка на основную публикацию
Adblock
detector