3

所以我承认我是 javascript 新手,并且我来自 C.+ 背景(“嗨,我是 Bob,我是基于类的静态语言用户”,合唱“嗨 Bob!”)。

我发现我经常最终编写如下函数:

function someFunc()
{
    if (arguments.length === 0 ){
       ...
    } else {
       ...
    }
}

(可能有三种这样的情况)。或者,或者,我将差异写入名称:

function someFuncDefault() { ... };
function someFuncRealArg(theArg) { ... };

(用“RealArg”代替一些语义上内容丰富的短语)。

这种事情有更好的模式吗?

4

8 回答 8

5

看看这个帖子

于 2009-02-17T22:35:12.897 回答
3

我不知道我会这样做,但似乎它可能会使您的代码稍微不那么难以管理:

function someFunc() {
    switch (arguments.length) {
        case 0: noArgs();
        case 1: oneArg(arguments[0]);
        case 2: twoArgs(arguments[0], arguments[1]);
    }
    function noArgs() {
        // ...
    }
    function oneArg(a) {
        // ...
    }
    function twoArgs(a, b) {
        // ...
    }
}

另一个例子可能是:

function someFunc(a, b) {
    if ('string' == typeof a) {
        // ...
    } else if ('number' == typeof a) {
        // ...
    }
}

当然,您可能会通过结合这两个示例来创建一些非常难以管理的东西(使用条件来确定基于参数数量和参数类型的行为)。

于 2009-02-17T22:30:55.637 回答
1

在 Javascript 中,所有参数都是可选的。

您可以尝试以下方法:

编辑(不会破坏“真实性”为假的值的更好方法):

function bar(arg1, arg2) {
  if(arg1 === undefined) { set default }
  if(arg2 === undefined) { set default }
  //do stuff here
}

打破虚假值的旧方法:

function foo(arg1, arg2) {
  if(!arg1) { set default }
  if(!arg2) { set default }
  //do stuff here
}

Douglas Crockford 的 javascript 讲座是开始使用 javascript 的好地方:http: //video.yahoo.com/search/ ?p=javascript

于 2009-02-17T22:35:46.233 回答
1

这是重载,而不是压倒一切,不是吗?

Javascript 是弱类型的,所以方法签名和本机支持不可用。我的建议是传递一个可扩展的对象作为单独的参数。根据需要检查和处理 param 对象上属性的存在。

与争论相比,这有什么优势?好吧,它可以让您在调用的地方明确说明您的意图,并且在您收到的地方明确 arg1 和 arg2 的含义,并且它可以让您抽象为您可以扩展功能的自定义数据对象类。

function someFunc(params)
{
  var x = params.x || defaultX;
  var y = params.y || defaultY;

  //businesslogic
}

someFunc({x:'foo',y:'bar'});

someFunc({y:'baz'});
于 2009-02-17T22:43:49.113 回答
0

Javascript 让你变得非常懒惰(不像 Python 那样懒惰,但相当懒惰)。

function someFunc(arg1, arg2)
{
  if(typeof(arg1) == "undefined") {
    arg1 = default;
  }
  ... 
}

所以你真的不需要超载。Javascript 不会因为传递错误数量的参数而对您大喊大叫。

于 2009-02-17T22:36:52.453 回答
0

每个人都接近了,我认为这里真正的问题是在 JavaScript 中你不应该根据传入的参数来改变行为。

由于 JavaScript 使所有参数都是可选的,因此您可以遵循使用此约定的简洁方法:

function foo(bar, baz) {
    bar = bar || defaultBar;
    baz = baz || defaultBaz;
    .
    .
    .
}
于 2009-02-17T23:00:56.563 回答
0

就个人而言,我更喜欢编写将要执行的最复杂的函数,然后将其记录在注释中,以便其他人知道他们不必发送所有参数。

//concat(str1, str2 [,str3 [,str4 [,str5]]])
function concat(str1, str2, str3, str4, str5) {
    var str = str1 + str2;
    if(str3 != undefined)
        str += str3;
    if(str4 != undefined)
        str += str4;
    if(str5 != undefined)
        str += str5;
    return str;
}

我还发现了参数顺序在普通函数中很重要的情况,但有时我想单独发送参数(即我想发送 str3 和 str5 而不是 str4)。为此,我使用一个对象并测试已知属性

//concat({str1:string, str2:string, str3:string, str4:string, str5:string})
//str3, str4, and str5 are optional
function concat(strngs) {
    var str = strngs.str1 + strngs.str2;
    if(strngs.str3 != undefined)
        str += strngs.str3;
    if(strngs.str4 != undefined)
        str += strngs.str4;
    if(strngs.str5 != undefined)
        str += strngs.str5;
    return str;
}
于 2009-02-18T03:40:18.420 回答
0

bob.js提供了更全面的重载机制:

var notify = new bob.fn.overloadFunction([ 
    { 
        condition: function(msg) { return bob.utils.isString(msg); }, 
        overload: function(msg) { 
            console.log(msg); 
        } 
    }, 
    { 
        condition: function(bSayHello) { return bob.utils.isBoolean(bSayHello); }, 
        overload: function(bSayHello, msg) { 
            msg = bSayHello ? 'Hello: ' + msg : msg; 
            console.log(msg); 
        } 
    } 
]); 

调用重载函数:

notify('Simple sentence.'); 
// Output: 
// Simple sentence. 
notify(true, 'Greeting sentence.'); 
// Output: 
// Hello: Greeting sentence. 
notify(123); 
// JavaScript Error: 
// "No matching overload found." 
于 2013-04-03T19:49:52.213 回答