防止全球范围的污染

Posted

技术标签:

【中文标题】防止全球范围的污染【英文标题】:Prevent the pollution of the global scope 【发布时间】:2014-04-09 10:25:11 【问题描述】:

我们正在尝试为我们正在处理的项目强制执行 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 代码,我们认为这是一个加分项,因为它会迫使开发人员遵循最佳实践。

附:是的,我知道最好的解决方案是代码审查,遗憾的是在我们的情况下它们不可行,所以我们正在寻找一个包罗万象的解决方案。

【问题讨论】:

【参考方案1】:

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

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

您可以通过以下方式阻止分配给 chrome 中的窗口。

Object.preventExtensions(window)

【讨论】:

您的解决方案不起作用:在 Firefox 27 中抛出 TypeError: can't change object's extensibility 异常并停止脚本的执行,在 Chrome 33 和 Internet Explorer 11 中不会抛出异常但不会阻止创建新对象。 你在哪里运行它?如果我在 Chrome 中打开控制台,这会阻止我创建变量或添加到窗口。这是 Chrome 33。 我制作了一个简单的 HTML 页面(您可以在 gist.github.com/kappa7194/9481918 找到代码)并将其托管在 IISExpress 中。不阻止使用var foo = 'foo'; 创建变量,只有window.bar = 'bar'; 被阻止并且仅在Chrome 中; Firefox 引发异常,Internet Explorer 默默地吞下错误。

以上是关于防止全球范围的污染的主要内容,如果未能解决你的问题,请参考以下文章

C++:如何防止私有名称污染派生类型?

javascript防止变量全局污染

*防止JS全局污染

为什么代码要写到匿名自执行函数中?

[Effective JavaScript 笔记]第44条:使用null原型以防止原型污染

防止js全局变量污染方法总结