如何处理仅由一个函数使用的函数

时间:2013-02-19 00:05:43

标签: javascript function language-agnostic

当一个调用一个或多个其他函数的函数和被调用的函数只被一个调用函数使用时,代码应该如何构造?

例如,如果funcB()funcC()仅由funcA()调用,则funcB()funcC()应为匿名函数或嵌套函数,或者如果他们只是被宣布为私人或被安排在内部阶级,他们是一个类的一部分?

我目前正在使用JavaScript,但在使用其他语言(如C ++和Java)时遇到了相同的情况。

根据Wikipedia JavaScript确实有嵌套函数,虽然我从未见过它?

4 个答案:

答案 0 :(得分:1)

如果funcB()funcC()在概念上与funcA()并不合理,那么您就不应该公开。

传统的OOP会说你应该把它们变成私人的。

我认为,funcB()funcC()几乎总是存在另一个概念。你应该在不同的类上使它们成为公共方法。无论持有funcA()持有该类的私有实例。

在抽象地谈论A,B和C时,很难为此提出令人信服的理由。但我会说,如果它们在概念上不属于funcA()那么它们在概念上属于其他东西。如果你同意这个前提并同意作文比继承更好,那么结论就是在其他一些课程上公开。

答案 1 :(得分:1)

当我开始一个项目时,我倾向于避免封装功能,直到事情变得稳定。

正如Dancrumb指出的那样,函数调用并不是免费的,所以你可能需要进行一些小的重构。但是,当你看到几个月没有碰过的代码时,那个漂亮干净的组织将对你的心理健康有益。当你在一个团队工作时,这个指数更加真实:)

答案 2 :(得分:0)

这里有很多方法。

Javascript支持匿名函数,可以在代码中的任何位置定义和分配给变量。

因此,你可以写:

function foo() {
  var bar = function() { /* some code */ };

  bar();
}

bar在其他任何地方都无法使用。这个可能对封装功能很有用,但我不认为它是一个非常可扩展的开发模型。

有一种思想流派认为,任何只召唤一次的功能在将来可能会被称为不止一次。在这种情况下,您可以创建“私有”功能:

var Foo = (function() {

  var Foo = function() {
    /* some constructor code */
  };

  var private = function() { /* a private function */ };

  Foo.prototype.public = function() {
    private();
    /* And some other stuff */
  };

  return Foo;

})();

var foo = new Foo();
foo.public(); /* Includes a call to the private method */

在这种情况下,您的private方法确实是私有的,因此您不必将内部工作暴露给全世界。

但实际上,这更多是关于如何实施访问修改的讨论。有很多信息可以回答这个问题。更大的设计问题是,是否实现单独的功能,或者是否只是内联它们。

我的选择通常是将有凝聚力的功能集合到...中,进入功能。函数调用的成本是非零的,但是在之后担心...如果你发现函数调用是性能瓶颈,那么你可以担心你是否在调用太多了,是否应该重构代码以减少使用次数。

在此之前,编写你的函数,调用它们并陶醉于清晰的代码中。只需确保使用好的方法名称:)

答案 3 :(得分:0)

如果funcB和funcC被创建为类中的闭包,并且您没有将这些“暴露”到接口,那么它们可以更改(删除,添加,返回不同的值等等)而不用担心他们是如何在课外实施的。

一旦他们被曝光,所有投注都会被取消,他们可能需要进行单元测试,支持等。这是众所周知的规则。

闭包只是在将要使用它的范围内声明的函数。

方法A

function MyClass(){

    function funcA(i){
        funcB(i);
        funcC(i);
    }
    function funcB(i){
        //...
    }
    function funcC(i){
        //...
    }
    return {funcA:funcA}
}
va mc = new MyClass()
for(var i = 0;i<100000;i++){    
    mc.funcA(i);
}

方法B:

function MyClass(){
    function funcA(){
        function funcB(){
        }
        function funcC(){
        }
        for(var i = 0;i<100000;i++){
            funcB();
            funcC();
        }
        // funcB, funcC are created before and then released after this
    }
    return {funcA:funcA}
}
va mc = new MyClass()
mc.funcA();

当多次调用funcA时,方法B可能不太受欢迎,因为赋值是最合理的。

在考虑内存时,方法B可能是首选。虽然它有争议,因为funcA和funcB都驻留在MyClass和MyClass.funcA中。