2

我面临一种情况,我需要在 JavaScript 中的多个函数的开头和结尾添加相同的代码块。例如

function funcA () {
    // code block 1
    ...

    // code unique to funcA
    ...

    // code block 2
    ...
}

function funcB () {
    // code block 1
    ...

    // code unique to funcB
    ...

    // code block 2
    ...
}

function funcC () {
    // code block 1
    ...

    // code unique to funcC
    ...

    // code block 2
    ...
}

我想知道在这里使用什么正确的模式来减少重复。

4

6 回答 6

6

它称为提取方法重构。

function block1() 
{
  // code block 1
}

function block2() 
{
  // code block 2
}

function funcA () {
    block1();

    // code unique to funcA
    ....

    block2();
}
function funcB () {
    block1();

    //   code unique to funcB
    ....

    block2();
}
function funcC () {
    block1();

    //   code unique to funcC
    ....

    block2();
}
于 2012-11-15T18:19:57.457 回答
4

您可以使用另一个函数为您构建函数:

function makeFunc( specialProcessing ) {
  return function() {
    // block 1
    specialProcessing( x, y, z );
    // block 2
  };
}

var func1 = makeFunc( function( x, y, z ) {
  // stuff for func1
});

var func2 = makeFunc( function( x, y, z ) {
  // stuff for func2
});
于 2012-11-15T18:23:06.083 回答
1

如果您在这些块中有相当大的代码块,可以通过简单地更改正在使用的变量来普遍应用于每个函数,那么您应该将这些代码块提取到单独的方法中。这具有促进代码重用、提高代码可读性以及使测试和调试变得更加容易的优势,特别是如果您遵循测试驱动的开发理念,甚至只是运行自己的功能测试。好的软件工程和设计的目标始终是创建在许多地方有用的小方法,以减少您必须做的工作并减少代码中的错误数量。

于 2012-11-15T18:21:08.380 回答
1

块可以提取到函数并使用 apply 方法调用。这将保留上下文并转发传递给原始函数的任何参数。

function funcA() {
    block1.apply(this, arguments);

    // specific code to funcA

    block2.apply(this, arguments);
}

arguments将包含传递给父函数的任何参数

于 2012-11-15T18:28:52.947 回答
0

如果您知道它总是会这样设置,并且您不希望在其中包含实际的函数调用,或者某些函数的顺序可能不同,我总是喜欢设置一个函数来交织函数调用我。

jsFiddle 演示

// Set up dynamically to handle calling any number of functions
// in whatever order they are specified in the parameters
// ie: setupFunctionOrder(func1, func2, func3, func4);

function setupFunctionOrder () {
    for (i = 0; i < arguments.length; i++) {
        arguments[i]();
    }
}

function block1 () { log('\nblock1 - running'); }
function block2 () { log('block2 - running'); }
function funcA () { log('funcA - running'); }

// ** Useage:
// now we make the actual call to set up the ORDER of calling -funcA-
setupFunctionOrder(block1, funcA, block2);
于 2012-11-15T18:30:47.497 回答
0

只需传入您想要唯一的功能。像这样:

function reusableFunc(fn) {
    //reused code block here
    fn();
    //reused code block here
}

var myResuableFunc1 = function (args) {
    reusableFunc(function () { 
        //do your business here.    
    });
};


var myResuableFunc2 = function (args) {
    reusableFunc(function () { 
        //do your business here.    
    });
};

//Or another way
function myResuableFunc3(args) {
    reusableFunc(function () { 
        //do your business here
    });
}

然后,您可以使用共享代码创建任意数量的函数,并通过闭包的强大功能,以您喜欢的任何方式传递这些新创建的函数。

于 2012-11-15T19:21:57.017 回答