如何防止修改JavaScript中的对象并防止它们在控制台中访问

本文概述

  • 对象冻结
  • Object.preventExtensions
  • 物体密封
  • 快速比较和注释
  • 防止在控制台中访问变量
有多种方法可以根据你的需要锁定对象。对象对象(尽管有冗余), 具有一些有用的功能, 可让你锁定对象。
  • 对象冻结
  • 物体密封
  • 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"}]};

对象冻结 冻结方法冻结对象(感谢队长)。
如何防止修改JavaScript中的对象并防止它们在控制台中访问

文章图片
此方法可防止向其添加新属性, 防止删除现有属性, 并防止更改现有属性(或其可枚举性, 可配置性或可写性)。本质上, 对象是不可变的。该方法返回冻结的对象。
// Add a property before being frozenmyBankAccount.bankName = "Gotham Merchant Bank"; // Shows the value in the object as the property// was created before the object has been frozenconsole.log(myBankAccount.bankName); // Freeze the objectObject.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 objectObject.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 BatmanmyBankAccount.user.flushMethod();

Object.preventExtensions preventExtensions方法可防止将新属性添加到对象(即防止将来对该对象进行扩展)。
// Add property before being nonExtensiblemyBankAccount.newValue = http://www.srcmini.com/12; // Disallow new properties to the bank accountObject.preventExtensions(myBankAccount); // Silently ignored or TypeErrormyBankAccount.flushAccount = function(){sendMoneyToJokerAccount(); }; console.log(myBankAccount.newValue); // Output :12// Method doesn't existmyBankAccount.flushAccount();

物体密封 密封方法可密封对象, 从而防止向其添加新属性并将所有现有属性标记为不可配置。只要可写, 当前属性的值仍可以更改。
// Seal objectObject.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 TypeErrordelete myBankAccount.user; // throws a TypeError myBankAccount.newPropertyToAdd = 'qwe'; // throws a TypeError

快速比较和注释
函数 使对象不可扩展 每个属性的可配置设置为false
Object.preventExtensions No
物体密封
对象冻结
  • 除非冻结对象, 否则冻结对象的子对象是可修改的。
  • 使用Object.seal的原型链保持不变。但是, __proto__属性也是密封的。
  • 属性仍然可以添加到对象原型。但是, 在对象上调用preventExtensions也将阻止对其__proto__属性的扩展。
Object变量具有一种有用的方法来检查对象是否使用了任何先前的功能:
  • Object.isFrozen(myObj)。
  • Object.isSealed(myObj)。
  • Object.isExtensible(myObj)。
除非你在代码中使用严格模式(” use strict” ; ), 否则不会在控制台中引发任何错误, 因为所有内容都将被静默忽略。但是, 在严格模式下, 如果尝试在不可扩展的对象中添加属性等来完成任务, 则会出现类型错误。
防止在控制台中访问变量 如果你担心有人可以签出你的代码并在控制台中进行修改, 则只需将你的代码包装在一个匿名函数中即可。这将阻止其出现在控制台中, 因此其他开发人员将无法以这种方式访问??代码。
分析以下代码:
< input type="button" id="transfer" value="http://www.srcmini.com/TransferToAccount" /> < input type="text" id="account" /> < input type="text" id="ammount" /> < script> 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 transactiondocument.getElementById("transfer").addEventListener("click", function(){// get required infovar amount = document.getElementById("amount").value; var accountTarget = document.getElementById("account").value; // Do transaction MySuperBankObject.sendMoneyToAccount(parseInt(accountTarget), parseFloat(amount)); }, false); < /script>

如果你在文档中包含此代码, 并且某人决定读取该文件的代码, 则由于MySuperBankObject对象是全局公开的, 因此他们可以在控制台中查找并执行以下代码:
如何防止修改JavaScript中的对象并防止它们在控制台中访问

文章图片
没有人想要吗, 对吗?为了防止这种情况(尽管该代码在浏览器中可见, 但是无法修改), 将先前的代码包装在一个匿名函数中:
(function(){/*** All the code that needs to be unexposed in the console here.*/})(); // Send parameters inside the function if you need to

【如何防止修改JavaScript中的对象并防止它们在控制台中访问】现在将前一个包裹在一个匿名函数中:
< input type="button" id="transfer" value="http://www.srcmini.com/TransferToAccount" /> < input type="text" id="account" /> < input type="text" id="ammount" /> < script> (function(){var allow_transaction = false; var MySuperBankObject = {person: "Bruce", account: 123123, ........})(); < /script>

有用吗?如果开发人员尝试在控制台中获取mySuperBankObject, 他将面临以下问题:
如何防止修改JavaScript中的对象并防止它们在控制台中访问

文章图片
该代码将按预期工作, 但是变量不再在控制台中公开。还要注意, 即使你的代码有弱点(getter和setter的配置错误, 即愚蠢的全局函数如getMySuperBankObject … )并且具有足够的知识, 但是仍不能被轻易修改, 尽管开发人员仍可以轻松地对其进行修改。 。精简代码以降低可读性。
最后, 请不要处理带有此帖子中所发布代码的银行帐户, 谢谢!
玩得开心

    推荐阅读