Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 测量全球环境污染 背景_Javascript_Namespaces_Refactoring - Fatal编程技术网

Javascript 测量全球环境污染 背景

Javascript 测量全球环境污染 背景,javascript,namespaces,refactoring,Javascript,Namespaces,Refactoring,我正试图重构一些又长又难看的Javascript(可耻的是,这是我自己的)。我开始学习Javascript时就开始了这个项目;这是一次很好的学习经历,但我的代码中有一些垃圾,我采用了一些相当糟糕的做法,其中主要是全局名称空间/对象(在我的例子中是窗口对象)的严重污染。在我努力减轻上述污染的过程中,我认为测量它会有所帮助 方法 我的直觉是,在加载任何代码之前,在加载第三方库之后,最后在执行代码之后,简单地计算附加到窗口的对象的数量。然后,当我重构时,我会尽量减少与加载代码相对应的增加)。为此,我使

我正试图重构一些又长又难看的Javascript(可耻的是,这是我自己的)。我开始学习Javascript时就开始了这个项目;这是一次很好的学习经历,但我的代码中有一些垃圾,我采用了一些相当糟糕的做法,其中主要是全局名称空间/对象(在我的例子中是
窗口
对象)的严重污染。在我努力减轻上述污染的过程中,我认为测量它会有所帮助

方法 我的直觉是,在加载任何代码之前,在加载第三方库之后,最后在执行代码之后,简单地计算附加到
窗口的对象的数量。然后,当我重构时,我会尽量减少与加载代码相对应的增加)。为此,我使用:

console.log(Object.keys(window.length)

在我的代码中的不同位置。这似乎工作正常,我看到数字在增长,特别是在我自己的代码加载之后。但是

问题 只要看看Chrome开发者控制台中
窗口
对象的内容,我就可以看出它并没有计算所有附加到该对象的内容。我怀疑它没有包括一些更基本的属性或对象类型,不管它们是属于浏览器、库还是我自己的代码。无论如何,有人能想出一种更好更准确的方法来度量全局名称空间污染,从而有助于重构吗


提前谢谢

根据经验,您选择的常规模式工作正常。然而,有两件事你可能需要考虑(作为补充或替代):

  • 使用或与现有代码一起使用,并查看产生的错误。它应该可以帮助您快速、轻松地发现大多数(如果不是全部的话)全局变量的用法(例如,您将看到“未定义”变量的错误)。这是一个非常简单的方法。因此,本例中的度量将仅着眼于问题的总数
  • 我们发现Chrome可以让检测窗口对象上泄漏的资源变得棘手(因为在运行页面的过程中添加了一些东西)。例如,我们需要使用RegExs检查返回的某些属性是否为本机属性:
    /\s*函数\w*\(\){\s*\[native code\]\s*}\s*/
    来发现本机代码。在我们编写的一些代码“泄漏检测”中,我们还尝试(在try-catch中)获取属性的值,以验证它是否设置为值(而不仅仅是未定义的)。但是,在你的情况下,这不应该是必要的
    所以在和留下一些评论之后,我找到了一个很好的解决方案。在加载任何库或我自己的代码之前,我创建
    仪表板
    全局对象(我唯一的目标对象),并通过以下方式存储附加到
    窗口
    的对象列表:

    var dashboard = {
        cache: {
            load: Object.getOwnPropertyNames(window)
        }
    };
    
    然后,在加载所有库之后但在加载我自己的任何代码之前,我修改了
    仪表板
    对象,添加
    污染
    方法(在新的
    调试
    命名空间中):

    在任何时候,我都可以从控制台调用此方法并查看

    全局命名空间被以下内容污染:
    53自定义对象
    44库对象


    以及两个列出与这些对象关联的键的数组。
    base
    library
    快照是静态的,而当前的自定义度量(通过
    custom
    )是动态的,因此如果我要通过AJAX加载任何自定义javascript,那么我可以重新度量并看到任何新的自定义“污染”

    例如,有什么附加到
    窗口
    ,但在您检查它时没有显示?@Utkanos,例如-在Chrome中,如果我导航到
    关于:空白
    ,只查看
    对象。键(窗口)
    ,只返回8个键(
    [“顶部”、“窗口”、“位置”、“外部”、“Chrome”、“v8Intl”、“v8Locale”,“document”]
    )。但如果只检查控制台中的
    窗口
    ,就有几百个键……我同意Felix的观点,但如果出于其他原因需要获取不可枚举的属性,则可以使用
    getOwnPropertyNames()
    然后沿着原型链走。Firebug呢?它显示了所有全局函数和变量。我同意这些添加。我使用JsLint,我发现它非常有用(但从未用于此目的。我想我会开始使用它)。@WPCoder您能澄清一下如何在从循环返回的所有对象上实现#2吗(在值上使用toString),该正则表达式用于查看它是什么类型的对象——如果它是内置的本机代码,则会被忽略。我们发现这些是在拍摄初始快照后的不同时间添加的(与您所做的非常相似)。我明白了。这非常有用。我必须实现它!谢谢。
    dashboard.debug = {
        pollution: (function() {
            var pollution,                                     
                base = cache.load, // window at load         
                filter = function(a,b) { // difference of two arrays
                    return a.filter(function(i) {
                        return !(b.indexOf(i) > -1);
                    });
                },                          
                library = filter(Object.getOwnPropertyNames(window), base), 
                custom = function() { 
                    return filter(Object.getOwnPropertyNames(window),
                            base.concat(library)); 
                };       
    
            delete cache.load;
    
            pollution = function() {
                console.log('Global namespace polluted with:\n ' + 
                        custom().length + ' custom objects \n ' +
                        library.length + ' library objects');
    
                return {custom: custom().sort(), library: library.sort()};
            };
    
            return pollution;
        }())  
    };