Javascript中静态函数声明和普通函数声明的区别是什么?

6

在JavaScript中,有多种声明函数的方式。其中一种方法是在类中声明一个静态函数,如下所示。

class className {
 static fucntionName() {
 }
}

另一种声明的方式是通过传统的JavaScript样式,如下所示。
function functionName() {
}

我想了解使用这两种情况的优缺点。静态方法有什么特定的用例吗?为什么要声明一个类(我们知道在JavaScript中不需要实例化类就可以访问静态函数)?为什么不在所有/任何用例中都使用传统的函数声明方式(上面示例中的第二种情况)?我想详细了解这个问题。

1
静态方法调用直接在类上进行,不能在类的实例上调用。静态方法通常用于创建实用函数。另一方面,导出语句用于从给定文件(或模块)导出函数、对象或基元。这两个语句具有不同的目的,不是同义词。当一个函数是OO编程中类的一部分时,它被称为__方法__:了解更多关于js中静态方法的信息 - Tom O.
仅使用static方法的类并不是类的正确应用。 - Felix Kling
@FelixKling 我认为这没有问题。而且根据许多来源,这也是相当好的做法。 - Rahul
不,这完全没有意义。你能链接一些这些来源吗?如果你只需要一个函数集合,可以创建一个带有这些函数的对象,或者现在使用模块,从模块中导出这些函数。不要滥用类作为函数的容器。 - Felix Kling
请查看静态文档上的示例代码(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static#From_another_static_method)。它展示了只有静态函数的类。我只是这个意思。 - Rahul
4个回答

2

static 方法可以从类本身调用,这一点你已经知道了。

static 方法可以从类的 实例 中调用,因此您必须在能够访问该方法之前创建一个对象。

例如,对于一个执行 return a+baddNumbers(var a, var b),是否真的有必要浪费内存来实例化类的对象才能添加这两个数字?不需要,你只需要结果,这就是使用静态方法的全部意义。

使用第一种样式允许您将方法分组到特定的类中(类似于命名空间)。也许您可以定义像 MathString 这样的类,它们都有 add 方法,但是以不同的方式实现。单独调用 add() 会很困惑,但是调用 Math.add()String.add() 不会。

另一方面,export 样式则完全不同。它允许您使用来自另一个模块的函数。

想象以下:

first_module.js

function cube(var x) {
    return x * x * x;
}

second_module.js

import { cube } from 'first_module'; // <-- ERROR
alert( cube(3) ); // <-- Undefined function

但是,如果你这样声明 first_module:

export function cube(var x) {
    return x * x * x;
}

第二个模块将会正常工作。

1
谢谢,通过数学和字符串的例子,我更好地理解了。我也明白了导出/导入,只是关于 function() {} 的问题。我应该在那里使用 export 一词,看起来它偏离了读者的理解。 - Rahul

2
我想了解使用这两种情况的优劣势。
这就像苹果和橘子一样。类不必被导出,模块也不必是一个类。虽然导出的模块可以是一个类。
是否有特定用例适用于静态方法?
当您希望类提供某些功能,但这不是特定于该类的单个实例的功能时。例如:var c = Point.interpolate(a, b, .5); 静态 interpolate 函数不属于它正在操作的任何点。更适合在提供此功能(插值点)的类上定义此函数为静态函数。
我们知道在JavaScript中没有必要实例化类以便访问静态函数。
这正是静态函数的定义,您无需实例化类即可调用它。这不是JS特有的。
为什么不在所有/任何用例中都使用传统的函数声明方式?
因为如我所说,类和模块并不一定是相同的东西。而且写起来更好/更清晰。
class Foo{
    ...
    static fn(){...}
}

than

class Foo {
    ...
}

Foo.fn = function(){...};

虽然最终,两者都只是略微超过了一点点。
function Foo(){...}
Foo.fn = function(){};
// + Foo.prototype stuff

但是类语法更加简洁。即使你只是扫描这段代码,也更容易阅读和理解。


谢谢您的回答。您的回答给了我关于静态方法很多的信息。 - Rahul
关于我的苹果和橙子,我的问题从来不是关于“导出”,我知道它是什么以及如何工作。我只是好奇静态函数与传统模块化函数的用例。我看到许多应用程序将其API调用/请求封装在具有静态函数的类中,而应用程序的其余部分具有模块化函数,这样做是否有任何优势?这是我的基本问题。我仍然感谢您的回答。 - Rahul
我看过很多应用程序,它们的API调用/请求被封装在一个带有静态函数的类中,而应用程序的其余部分具有模块化函数。@rahulreddy你能提供一个例子吗?因为我脑海中没有任何结构类似的库。对我来说,按照这种方式做有点傻,至少从这个描述中我想象的结构是这样的。如果您能添加一个例子,那么这可能会改进/澄清问题。 - Thomas
你可以查看这篇文章,其中定义了会话API类。 http://www.thegreatcodeadventure.com/jwt-authentication-with-react-redux/ - Rahul

1
声明一个静态函数是在类中创建一个类级别的函数,该函数不能被该函数的实例调用。这种情况的一个例子是 Object.assign 函数。静态函数常用于构建对其定义的类型的实例进行操作的函数。

0
一个静态方法只能在类内部调用,适用于实用函数,例如处理传入的参数变量或设置常量(或前面提到的 Object.assign),当每次必须这样做以避免不必要的内存使用时。一旦清理完毕,您可以导出其余的函数以供在代码中的其他地方进行实例化,在那里参数将被清理/常量设置,每次使用该类时都会再次进行,而您的实例化可以专注于动态内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接