导出的 class 中可以有私有成员吗?

Can there be private members in an exported class?

我知道 node.js 中的所有内容都是私有的,除非您将其导出。

我找不到导出整个 class 的其他方法,但我的目标是使 privateMethod() 无法从 class 导入和实例化的位置访问。

#!/usr/bin/env node

'use strict'

module.exports = class DBConnector {
    constructor() {}
    publicMethod() {}
    privateMethod() {}
}

是否有解决方案,或者我必须离开它public?

在此先感谢您的帮助。

2021 年编辑:

Javascript 有一项针对私人 members/methods 的提案(截至 2021 年初,目前处于第 3 阶段)。有关详细信息,请参阅此 description on MDN。其中一部分已在 Chrome 和 Nodejs 中实现,尚未在 Safari 和 Firefox 中实现。

要使用此功能,请在方法前加上 # 前缀,如:

class ClassWithPrivateMethod {
  #privateMethod() {
    return 'hello world'
  }

  getPrivateMessage() {
    return this.#privateMethod()
  }
}

这将是不支持此功能的 Javascript 引擎中的语法错误。


2019 年的原始答案。

私有成员的解决方法。

Javascript 本身并没有私有方法的概念。因此,如果您在 class 上定义一个方法,那么任何引用该 class 实例的代码都可以调用该方法。在 Javascript.

中没有私有方法定义之类的东西

就是说,有许多解决方法可以为您提供对私有对象进行操作的代码,该对象不可从模块外部调用。这是一个例子:

'use strict'

// declare privateMethod as a local function that can only be called from within this module
function privateMethod(obj, args) {
   // private code here
   // reference instance with obj.method() or obj.data
   obj.otherPublicMethod()
}

module.exports = class DBConnector {
    constructor() {}
    publicMethod() {
        // call code for private method
        privateMethod(this, ...);
    }
    otherPublicMethod() {}
}

这是真正私有的,因为该方法的代码不在原型上,因此无法从该模块外部发现或调用。当然,你必须稍微不同地调用它,因为它不是一个“真正的”方法。但是,那是因为所有“真正的”方法都可以从外部发现和调用。


如果你想让私有方法本身使用this引用当前对象,那么你只要改变调用方法的方式即可:

'use strict'

// declare privateMethod as a local function that can only be called from within this module
function privateMethod(args) {
   // private code here
   // can reference this as in any normal method this.method() or this.data
   this.otherPublicMethod()
}

module.exports = class DBConnector {
    constructor() {}
    publicMethod() {
        // call code for private method using .call()
        privateMethod.call(this, ...);
    }
    otherPublicMethod() {}
}

仅供参考,TypeScript 支持私有方法和属性。 an article 让您了解它是如何工作的。当然,这意味着购买整个 TypeScript 语法并进行类型检查和转译您的代码。


这里还有一种基于闭包的实现私有方法和私有实例变量的方法:http://crockford.com/javascript/private.html。但这意味着您不能在 class 定义或原型上放置任何希望访问私有方法的方法。但是,它确实有效。