Javascript 中的函数重载 - 最佳实践

IT技术 javascript overloading
2021-01-18 19:14:11

在 Javascript 中伪造函数重载的最佳方法是什么?

我知道不可能像在其他语言中那样在 Javascript 中重载函数。如果我需要一个函数有两个用途foo(x)foo(x,y,z)这是最好的/优选的方法:

  1. 首先使用不同的名称
  2. 使用可选参数,如 y = y || 'default'
  3. 使用参数数量
  4. 检查参数类型
  5. 或者怎么做?
6个回答

使用参数进行函数重载的最佳方法是不检查参数长度或类型;检查类型只会使您的代码变慢,并且您会享受数组、空值、对象等的乐趣。

大多数开发人员所做的是将一个对象作为他们方法的最后一个参数。这个对象可以容纳任何东西。

function foo(a, b, opts) {
  // ...
  if (opts['test']) { } //if test param exists, do something.. 
}


foo(1, 2, {"method":"add"});
foo(3, 4, {"test":"equals", "bar":"tree"});

然后你可以在你的方法中以任何你想要的方式处理它。[开关,if-else等]

您能否提供一个 foo() 的示例实现来说明如何使用/引用这些“opts”参数?
2021-03-13 19:14:11
萌//可能是这样的; if(opts['test']) //if test param exists, do something.. if(opts['bar']) //if bar param exists, do something
2021-03-18 19:14:11
我很惊讶没有人已经问过这个问题:为什么arguments.length不推荐检查另外,我以前来过这里并阅读了大多数开发人员所做的是...,但我确定这是我见过的唯一完成的地方。这种方法也破坏了“重载”的句法甜度!
2021-03-19 19:14:11
这不是函数重载。函数重载是有两个独立的函数,名称相同但参数不同。您所描述的只是一个最后带有对象参数的函数。
2021-03-23 19:14:11
@user1334007 不可能像在 Java/.NET 中那样进行函数重载。是的,这不是“完全”重载,但它可以完成工作。
2021-04-05 19:14:11

我经常这样做:

C#:

public string CatStrings(string p1)                  {return p1;}
public string CatStrings(string p1, int p2)          {return p1+p2.ToString();}
public string CatStrings(string p1, int p2, bool p3) {return p1+p2.ToString()+p3.ToString();}

CatStrings("one");        // result = one
CatStrings("one",2);      // result = one2
CatStrings("one",2,true); // result = one2true

JavaScript 等效项:

function CatStrings(p1, p2, p3)
{
  var s = p1;
  if(typeof p2 !== "undefined") {s += p2;}
  if(typeof p3 !== "undefined") {s += p3;}
  return s;
};

CatStrings("one");        // result = one
CatStrings("one",2);      // result = one2
CatStrings("one",2,true); // result = one2true

这个特殊的例子实际上在 javascript 中比在 C# 中更优雅。未指定的参数在 javascript 中为“未定义”,在 if 语句中计算为 false。但是,函数定义并没有传达 p2 和 p3 是可选的信息。如果需要大量重载,jQuery 已经决定使用一个对象作为参数,例如 jQuery.ajax(options)。我同意他们的观点,这是最强大且可清晰记录的重载方法,但我很少需要超过一两个快速可选参数。

编辑:根据 Ian 的建议更改 IF 测试

是什么意思===!==为什么不直接使用==and !=
2021-03-14 19:14:11
未指定的参数undefined在 JS 中,而不是null. 作为最佳实践,您永远不应该将任何设置为undefined,因此只要您将测试更改,就不会有问题p2 === undefined
2021-03-16 19:14:11
如果你false作为最后一个参数传递,那么它不会连接"false"到最后,因为它if(p3)不会分支。
2021-03-22 19:14:11
只是一个简短的说明,您typeof p2 === "undefined"的示例可能与您期望的相反,我认为typeof p2 !== "undefined"这就是您的意图。另外,我可以建议它应该连接您实际执行的字符串、数字和布尔值吗?p2 === "number"; p3 === "boolean"
2021-03-22 19:14:11
我喜欢这样做:p3 = p3 || '默认值';
2021-03-25 19:14:11

JavaScript 中没有真正的函数重载,因为它允许传递任意数量的任意类型的参数。您必须在函数内部检查传递了多少参数以及它们的类型。

John Resig 的函数重载在这里ejohn.org/blog/javascript-method-overloading
2021-03-18 19:14:11
John Resig(jQuery 的)曾经尝试过这个,但这种尝试纯粹是学术性的,并没有提供任何真正的好处。
2021-03-22 19:14:11
“这个函数不会改变世界,但它简短、简洁,并使用了一个晦涩的 JavaScript 功能——所以它在我的书中获胜。” :-)
2021-03-24 19:14:11
@Terrance:我也喜欢 Resig 的方法。它就像一个魅力。我只需要找到一种方法来为其创建测试以验证用例。
2021-03-25 19:14:11

正确答案是在 JAVASCRIPT 中没有重载。

功能内部的检查/切换不是过载。

重载的概念:在某些编程语言中,函数重载或方法重载是创建多个具有不同实现的同名方法的能力。对重载函数的调用将运行适合调用上下文的该函数的特定实现,允许一个函数调用根据上下文执行不同的任务。

例如, doTask() 和 doTask(object O) 是重载方法。要调用后者,必须将对象作为参数传递,而前者不需要参数,并且使用空参数字段调用。一个常见的错误是在第二个方法中为对象分配一个默认值,这将导致不明确的调用错误,因为编译器不知道使用这两个方法中的哪一个。

https://en.wikipedia.org/wiki/Function_overloading

所有建议的实现都很棒,但说实话,JavaScript 没有本机实现。

好吧,有 87 人投了赞成票,就是这样。模拟这样的功能只是浪费时间。不管你喜不喜欢,JavaScript 没有这个特性,所以人们应该知道。
2021-03-18 19:14:11
终于有正常答案了!JAVASCRIPT 中没有重载。
2021-03-20 19:14:11
OP 要求一种伪造重载的方法。
2021-04-04 19:14:11
正如我之前说过的,我们在这里确实教育人们,我们不只是在没有验证他们问的问题是否正确的情况下就给他们答案。
2021-04-04 19:14:11
当您应该专注于预期含义时与人类争论字面含义与在编译器仅响应代码的字面含义时与编译器争论您的预期含义一样错误。OP 的目的显然是为了在调用站点之间实现与重载提供的类似效果,同时承认 JS 不支持该构造。
2021-04-04 19:14:11

有两种方法可以更好地解决这个问题:

  1. 如果您想留下很大的灵活性,则传递字典(关联数组)

  2. 以对象为参数,使用基于原型的继承来增加灵活性。

这是我最初的想法,但是,如果您正在创建的函数要在库中或由其他人使用,则简单地枚举这些值可能会有所帮助
2021-03-15 19:14:11