本文概述
- 对象冻结
- 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"}]};
对象冻结 冻结方法冻结对象(感谢队长)。
文章图片
此方法可防止向其添加新属性, 防止删除现有属性, 并防止更改现有属性(或其可枚举性, 可配置性或可写性)。本质上, 对象是不可变的。该方法返回冻结的对象。
// 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.isFrozen(myObj)。
- Object.isSealed(myObj)。
- Object.isExtensible(myObj)。
防止在控制台中访问变量 如果你担心有人可以签出你的代码并在控制台中进行修改, 则只需将你的代码包装在一个匿名函数中即可。这将阻止其出现在控制台中, 因此其他开发人员将无法以这种方式访问??代码。
分析以下代码:
<
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对象是全局公开的, 因此他们可以在控制台中查找并执行以下代码:
文章图片
没有人想要吗, 对吗?为了防止这种情况(尽管该代码在浏览器中可见, 但是无法修改), 将先前的代码包装在一个匿名函数中:
(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, 他将面临以下问题:
文章图片
该代码将按预期工作, 但是变量不再在控制台中公开。还要注意, 即使你的代码有弱点(getter和setter的配置错误, 即愚蠢的全局函数如getMySuperBankObject … )并且具有足够的知识, 但是仍不能被轻易修改, 尽管开发人员仍可以轻松地对其进行修改。 。精简代码以降低可读性。
最后, 请不要处理带有此帖子中所发布代码的银行帐户, 谢谢!
玩得开心
推荐阅读
- 如何使用javascript将URL(网站,电子邮件)从字符串转换为html标签
- 如何使用XMLHttpRequest(jQuery Ajax)绕过”Access-Control-Allow-Origin”错误
- 鸿蒙初体验-五子棋
- 在校生下午试题60分通过软考网工经验谈!
- 预告(2009年下半年软考试题及答案51CTO将实时发布)
- iOS开发面试只需知道这些,技术基本通关!(内存管理篇)
- 十年磨一剑 我的十年IT感言
- 软考,我该怎么对待你
- 谈谈网工考试的价值