2014-03-06 89 views
4

我们正在努力为我们正在进行的项目实施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.freezeObject.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.是的,我知道最好的解决方案是代码审查,可惜他们在我们的情况下不可行,所以我们正在寻找一个全面的解决方案。

回答

-1

要锁定来自var关键字的全局变量,请将您的代码封装在匿名闭包中。

(function(){ 
    // ... Your code ... 
}(); 

您可以通过以下方式阻止在chrome窗口中进行分配。

Object.preventExtensions(window) 
+0

您的解决方案不起作用:在Firefox 27将抛出'类型错误:不能改变对象的extensibility'异常,并停止脚本的执行,在Chrome 33和Internet Explorer 11不会抛出异常,但不不妨碍创建新对象。 – Albireo

+0

你在哪里运行它?如果我在Chrome中打开控制台,这会阻止我创建变量或添加到窗口。 这是Chrome 33. – fnln

+0

我做了一个简单的HTML页面(你可以在https://gist.github.com/kappa7194/9481918找到代码),并将它托管在IISExpress中。用'var foo ='foo';'创建一个变量不会被阻止,只有'window.bar ='bar';'被阻塞,并且仅在Chrome中; Firefox引发异常,Internet Explorer默默吞下该错误。 – Albireo