1

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

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

#!/usr/bin/env node

'use strict'

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

有没有解决方案,还是我必须将其公开?

提前感谢您的帮助。

4

1 回答 1

4

2021年编辑:

Javascript 有一个针对私有成员/方法的提案(目前处于 2021 年初的第 3 阶段)。有关详细信息,请参阅MDN 上的此描述。其中一部分在 Chrome 和 Nodejs 中实现,但尚未在 Safari 和 Firefox 中实现。

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

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

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

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


2019年的原始答案。

私人成员的解决方法。

Javascript 本身并没有私有方法的概念。因此,如果您在一个类上定义一个方法,那么任何引用该类实例的代码都可以调用该方法。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 支持私有方法和属性。这是一篇文章,可让您了解其工作原理。当然,这意味着购买整个 TypeScript 语法、类型检查和代码转换。


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

于 2019-12-02T18:32:57.747 回答