【问题标题】:Undertanding JavaScript methods了解 JavaScript 方法
【发布时间】:2022-10-01 23:56:00
【问题描述】:

我对 JavaScript 很陌生,来自 Java 背景。我只是在玩 NodeJS (\"type\": \"module\") Express 框架,但在两种用 JS 编写方法的方法之间徘徊。

以下是示例(在线检查相机)。

类型 1:

main.js

const method1 = () => {
    ...
    method2();
    ...
};

const method2 = () => {
    // this is not exported, so it works as a private method and won\'t be accessible in other JS files
    ...
};

.
.
.
// likewise there can be many other methods here

export { method1 }; // export other methods as well

然后,我可以在任何其他 JS 文件中使用method1(不能使用method2,因为它没有导出),如下所示:

test.js

import { method1 } from \'./main.js\';

method1();

类型 2:

main.js

class Main {
    
    method1() {
        ...
        method2();
        ...
    }

    #method2() {
        // this is a private method, so won\'t be accessible outside of this class
        ...
    }

    // likewise other methods here
}

const main = new Main();

export default main;

然后,我可以在任何其他 JS 文件中使用这个类实例,如下所示:

test.js

import main from \'./main.js\';

main.method1();

我想知道这两者有什么区别,什么时候用哪个,哪个更好。

  • 这是基于意见的。即使存在一些细微的客观差异(例如给定的 JS 环境是否支持私有方法语法),也无法明确回答。这个问题基本上归结为你喜欢OOP还是FP的风格封装。
  • 我了解 OOP,但什么是 FP 风格?
  • 函数式编程。在您的第一个示例中,您使用模块系统从导入该文件的代码中封装“method2”。这在允许您定义独立函数和/或缺乏面向对象的语言中更为典型。
  • 啊,明白了,所以你的意思是说,以上两种类型基本相同,可以根据个人喜好使用(WRT JS)?
  • @JigneshM.Khatri 您的 sn-ps 之间的最大区别在于对象。您可以多次实例化new Main(),并且可以分别在每个对象中保持状态。如果您需要这样做,请使用class。如果您不需要具有不同数据的多个实例,并且不需要保持状态,则不应使用classes 并使用简单的无状态静态函数。

标签: javascript node.js ecmascript-6


【解决方案1】:

两种方法都可以正常工作,但是类型 2 有点奇怪,因为您使用的是一个类只要防止某些东西被出口。

类通常用于组合在一起数据(类实例的属性)方法对这些数据进行操作。举个愚蠢的例子:

class NumberMultiplier {
  constructor(num) {
    this.num = num;
  }
  multiply(mult) {
    return this.num * mult;
  }
}
const n = new NumberMultiplier(5);
console.log(n.multiply(10));

上面,有数据(this.num),还有一种对数据进行操作的方法 (multiply)。

但是在您的情况下,您不希望拥有实例数据-您只想将函数组合在一起,实际上没有理由使用类。您可以考虑单独定义函数 - 就像在第一个 sn-p 中所做的那样 - 或者您可以使用导出的普通对象,仅包含您需要的属性:

const method2 = () => {
};
export default {
  method1() {
    method2();
  }
};

如果你拥有持久数据并希望将其放在类实例上,使用类和# 私有方法是可能的(使用new 创建单个实例,然后导出该实例是singleton 的示例)。

需要注意的一个潜在问题是,如果您将export default 与对象一起使用,则在单行中导入时无法提取导出的单个属性。也就是说,如果你只有一个默认导出,你就不能做类似的事情

import { method1 } from './main.js'.default;

你只能做

import theObj from './main.js';
const { method1 } = theObj;

有些人会认为这看起来有点难看。拥有独立的命名导出可以使模块的使用者更容易在一行中仅将他们需要的内容导入独立标识符中。

【讨论】:

  • 我上面给出的示例只是为了表示,这就是为什么我没有包含类变量等。当然,我们可以在Type 1中定义变量而不导出它们,那么它们将被视为类的实例的私有变量。所以,基本上我看不出它们有什么区别。
  • @JigneshM.Khatri 第一个 sn-p 中的模块提供了一个隐式单例。如果您有状态变量,请避免这种情况,如果您需要多个实例,显然它不起作用。
  • 感谢@Bergi 和一定的表现。保持变量的状态在我猜的两种方法之间有一个确切的区别。这就是我一直在寻找的,再次感谢。
  • 除此之外,我只是好奇,就像在 FP 风格中我们有任何功能或任何可以与 constructor 相似的东西,它只会在该模块加载时自动执行一次。
  • @JigneshM.Khatri 模块中的任何顶级代码都会在模块加载时执行。
【解决方案2】:

与您熟悉的 Java 不同,JS 中的类在没有明确必要时很少使用。然而,在某些情况下,JS 中的 OOP 可能非常有用。

基本上,第一种方法(类型 1) 如果您只是在进行一般的 JS 编程(例如前端网站或应用程序),那么您将在 99% 的时间内使用/查看。

但是,如果您正在制作游戏,则可以使用 OOP 更好地控制游戏中的不同角色/对象。

在后端或基础设施层面,这真的取决于。你可以完美地使用类(类型 2) 如果您关注MVC design pattern,但又是可选的。

最后,它归结为您自己的设计选择。你可以选择 FP (T1) 或 OOP (T2) 只要你喜欢在 JS 中,虽然有一些“行业标准”针对某些场景来决定何时使用哪个。

【讨论】:

  • 很酷,所以从@JaredSmith 的 cmets 和您的回答中,我发现上述两种类型对于 JS 来说都是相似的,并且它符合用户的偏好。顺便说一句,我在这里只谈论后端。尽管如此,我发现Type2 对我更有吸引力(我的 Java 习惯:P)。
【解决方案3】:

这实际上取决于您要导出的内容。这1型如果您只导出一个或几个对象,则更合适。和1型,您可以导出任何原始类型变量或对象,并且可以直接在main.js.

但是,如果要导出许多对象和/或变量,则类型 2说得通。和类型 2,所有导出都存储在一个对象中,因此您必须使用此对象访问它们。 性能方面两者是相同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-11
    • 2014-12-17
    • 2016-07-06
    • 2014-07-20
    • 2015-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多