我们正在努力为我们正在进行的项目实施JavaScript最佳实践,我们试图设置的一个限制是不污染全球范围。防止污染全球范围
我们有用于每个页面的结构像这样的HTML模板:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
</head>
<body>
<h1>Test</h1>
<!-- Page content here -->
<script src='https://code.jquery.com/jquery-2.1.0.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.js'></script>
<!-- Page scripts here -->
</body>
</html>
我试图做的是“锁定” window
对象,并防止任何除了它(例如var foo = 'foo';
在全球范围内或window['foo'] = 'foo';
)在页脚本运行之前,但在库加载之后。
我已经看了Object.freeze
,Object.seal
但他们没有为window
对象(他们提出一个TypeError: can't change object's extensibility
除外)工作。
我也看了像这样的“清理”脚本:
// Include this after the libraries.
(function(window) {
var cache = {};
for (var key in window) cache[key] = key;
window.cache = cache;
})(window);
// Include this after all scripts.
(function(window) {
var taint = {};
for (var key in window) taint[key] = key;
for (var key in window.cache) = delete taint[key];
for (var key in taint) delete window[key];
})(window);
,但他们只清理全球范围内,它们不会使第一空间的污染。
是否可以做到这一点?我们不在乎解决方案是否打破了污染全球范围的JavaScript代码,我们会认为它是一个加号,因为它会迫使开发人员遵循最佳实践。
P.s.是的,我知道最好的解决方案是代码审查,可惜他们在我们的情况下不可行,所以我们正在寻找一个全面的解决方案。
您的解决方案不起作用:在Firefox 27将抛出'类型错误:不能改变对象的extensibility'异常,并停止脚本的执行,在Chrome 33和Internet Explorer 11不会抛出异常,但不不妨碍创建新对象。 – Albireo
你在哪里运行它?如果我在Chrome中打开控制台,这会阻止我创建变量或添加到窗口。 这是Chrome 33. – fnln
我做了一个简单的HTML页面(你可以在https://gist.github.com/kappa7194/9481918找到代码),并将它托管在IISExpress中。用'var foo ='foo';'创建一个变量不会被阻止,只有'window.bar ='bar';'被阻塞,并且仅在Chrome中; Firefox引发异常,Internet Explorer默默吞下该错误。 – Albireo