【问题标题】:Advice on refactoring large JavaScript methods关于重构大型 JavaScript 方法的建议
【发布时间】:2012-07-18 14:00:16
【问题描述】:

在这种情况下,该网站是一个只能在 IE6 上查看的内部网站。目标是让它在 IE9 中可见。有几个仅适用于 IE 的脚本,例如使用xml data islands,通过点符号访问文档元素,即resulttable.style.display = "block"; 等......上述对于手头的问题可能有点多余,但它可以提供一些见解.

在整个网站中,有大量的 JavaScript 方法,它们非常庞大且难以调试。给你一个想法,有超过 100 个 JS 文件,每个平均大约 1000 行。

以下是省略了所有名称/逻辑的实际方法。所有的返回值都依赖于之前的逻辑:

function someMethod() {
if (stuff) {
    // operations
    if (stuff) {
        // operations
        for (loop) {
            // operations
            if (stuff) {
                // operations
                if (stuff) {
                    // operations
                    for (loop) {
                        if (stuff) {
                            // operations
                        }
                    }
                    // operations
                }
                else {
                    // operations
                    if (stuff) {
                        // operations
                    } else {
                        // operations
                    }
                }
                // operations
            }
        }

        // operations

        if (stuff) {
            // operations
            if (stuff) {
                // operations
                if (stuff) {
                    // operations
                    for (stuff) {
                        // operations
                        if (stuff) {
                            // operations
                        } else {
                            // operations
                        }
                    }
                    if (stuff) {
                        // operations
                        if (stuff) {
                            // operations
                            for (loop) {
                                // operations
                            }
                            // operations
                            for (loop) {
                                if (stuff) {
                                // operations
                                }
                            }
                        }
                        // operations
                        if (stuff) {
                            // operations
                        }
                        return something;
                    }
                    else {
                        // operations
                        return something;
                    }
                }
                else {
                    // operations
                    if (stuff) {
                        // operations
                        return something;
                    }
                    else {
                        // operations
                        if (stuff) {
                            // operations
                        }
                        // operations
                        return something;
                    }
                }
            }
        }
        return something;
    }
    else {
        // operations
        return something;
    }
}
return something;
}

在处理旧网站时,您有什么建议将 JavaScript 方法分解成更易于管理的部分?

免责声明:我的 JS 技能处于平均水平。我们现在想避开 JQuery。

【问题讨论】:

  • jQuery 会为你做很多 ifs(我假设这些 ifs 与你所说的每个浏览器特性有关),所以我认为学习它并把它用于重构您的代码。
  • 我建议你使用一个工具。请参阅我的question 和提供的答案
  • @davidbuzatto - 这些是大型逻辑流程语句;与浏览器特性无关。也许帖子没有传达这一点,但当前网站是为 IE6 设计的,没有其他浏览器。
  • 我真的不认为这是特定于 javascript 的。如果一个方法太大,把它拆分成几个逻辑方法,使其更具可读性。
  • 首先,我将开始为每个 js 文件创建命名空间,并仅使用该文件的功能填充这些命名空间。类似于: var MyNamespace = {}; MyNamespace.myFunction1 = function() {};等等。有了这个,我将开始重构每个函数,提取整个系统通用的块并将它们插入到 Utils 命名空间中,例如,特定于我正在工作的命名空间的块。提取后,我将开始重构每个功能,不使用任何专有功能。最后,我将对结果进行更多模块化。

标签: javascript refactoring legacy-code


【解决方案1】:

您可以简单地将 someMethod() 分解为可以重复逻辑的单独函数。

此外,无需查看您拥有的特定逻辑并找到最适合该逻辑的模式,一些可能有帮助的一般模式是

模块模式,例如

var MyModule = function() {
    function privateFn() {
    }
    function publicFn() {
    }
    function doWork(args) {
    }

    return {
        publicFn: publicFn,
        doWork: doWork,
    };
}();
MyModule.doWork({ param1: 'test', param2: true});

原型继承可用于类似于 c#/Java 中的类,例如

var MyClass = function(args) {
    this.prop1 = 'test'
    this.prop2 = args.param1;
};
MyClass.prototype.doWork = function(args) {
};
var myInstance = new MyClass({ param1: 'test' });
myInstance.doWork({ param1: true });

您可以使用命名空间来组织这些,例如

if (window.MyNamespace === undefined) window.MyNamespace = {};
MyNamespace.MyModule = function () { ... };
MyNamespace.MyClass = function () { ... };
MyNameSpace.MyModule.doWork();

其他可能有帮助的模式可以在这里找到http://shichuan.github.com/javascript-patterns/

【讨论】:

  • 这些都是好方法;我并不完全了解在基于类的结构中使用 JS。在Module Pattern 的第一个示例中,您包含了privateFn;这是一个真正私有的方法,只能在MyModule 中访问吗?我不确定我看到它与publicFn 有何不同。它们的访问方式有何不同?
  • js-patterns 的绝佳链接,顺便说一句!
  • 模块模式创建在包装函数范围内的函数。此方法的返回仅包括您要公开的函数,因此其他函数在 MyModule 对象中不可用。以jsfiddle.net/chrish/Wvh2H 为例
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2017-09-01
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多