Подтвердить что ты не робот

Измерение загрязнения глобального пространства имен

Фон

Я пытаюсь реорганизовать некоторый длинный, уродливый Javascript (позорно, это мой собственный). Я начал проект, когда начал изучать Javascript; это был отличный опыт в обучении, но в моем коде есть некоторый мусор, и я использую некоторые довольно плохие практики, среди которых главное загрязнение глобального пространства имен/объекта (в моем случае, объекта window). В моих усилиях по смягчению указанного загрязнения, я думаю, было бы полезно его измерить.

Подход

Мой инстинкт кишки состоял в том, чтобы просто подсчитать количество объектов, прикрепленных к объекту window, до загрузки любого кода, снова после загрузки сторонних библиотек и, наконец, после моего кода. Затем, когда я рефакторинг, я попытался бы уменьшить увеличение, соответствующее загрузке моего кода). Для этого я использую:

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

в разных местах моего кода. Кажется, это работает нормально, и я вижу, что число растет, особенно после загрузки моего собственного кода. Но...

Проблема

Просто посмотрев содержимое объекта window в консоли Chrome Developer, я вижу, что он не подсчитывает все, что привязано к объекту. Я подозреваю, что это не включает в себя некоторые более фундаментальные свойства или типы объектов, независимо от того, принадлежат ли они браузеру, библиотеке или моему собственному коду. В любом случае, может ли кто-нибудь подумать о более точном и точном способе измерения глобального загрязнения пространства имен, которое могло бы помочь в рефакторинге?

Спасибо заранее!

4b9b3361

Ответ 1

Выбранный вами общий шаблон работает нормально. Однако есть две вещи, которые вам, возможно, потребуется рассмотреть (как дополнения или альтернативы):

  • Используйте JsLint.com или JSHint.com свой существующий код и посмотрите на возникшие ошибки. Это должно помочь вам быстро и легко определить большинство, если не все использование глобальных переменных (например, вы увидите ошибки "undefined" ). Это очень простой подход. Таким образом, измерение в этом случае будет просто смотреть на общее количество проблем.
  • Мы обнаружили, что Chrome может затруднить обнаружение утечки ресурсов в объекте окна (поскольку вещи добавляются в ходе запуска страницы). Нам нужно проверить, например, чтобы узнать, являются ли определенные свойства возвращенными, с помощью RegExs: /\s*function \w*\(\) {\s*\[native code\]\s*}\s*/ для определения собственного кода. В некотором коде кода "обнаружение утечки", который мы написали, мы также пытаемся (в try catch) получить значение свойства, чтобы убедиться, что оно установлено в значение (а не только undefined). Но это не должно быть необходимо в вашем случае.

Ответ 2

Итак, после некоторых комментариев, оставшихся Felix Kling и Lèse majesté, я нашел решение это хорошо работает. Перед загрузкой каких-либо библиотек или моего собственного кода я создаю глобальный объект dashboard (только для моего намеренного) и сохраняю список объектов, прикрепленных к window, с помощью:

var dashboard = {
    cache: {
        load: Object.getOwnPropertyNames(window)
    }
};

Затем, после загрузки всех библиотек, но до загрузки любого из моего собственного кода, я изменяю объект dashboard, добавляя метод pollution (в новом пространстве имен debug):

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;
    }())  
};

В любой момент я могу вызвать этот метод с консоли и увидеть

Глобальное пространство имен загрязнено:
 53 пользовательских объекта
 44 объекта библиотеки

а также два массива, в которых перечислены ключи, связанные с этими объектами. Снимки base и library являются статическими, тогда как текущее пользовательское измерение (через custom) является динамическим, так что, если бы я загружал любой пользовательский javascript через AJAX, я мог бы переоценить и увидеть любое новое пользовательское "загрязнение",