导出的类中可以有私有成员吗? [复制]

Posted

技术标签:

【中文标题】导出的类中可以有私有成员吗? [复制]【英文标题】:Can there be private members in an exported class? [duplicate] 【发布时间】:2020-03-27 09:44:00 【问题描述】:

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

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

#!/usr/bin/env node

'use strict'

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

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

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

2021 年编辑:

javascript 有一个针对私有成员/方法的提案(目前处于 2021 年初的第 3 阶段)。有关更多详细信息,请参阅此description on 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 支持私有方法和属性。这是an article,它让您了解它是如何工作的。当然,这意味着购买整个 TypeScript 语法、类型检查和代码转换。


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

【讨论】:

以上是关于导出的类中可以有私有成员吗? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 C++ 中转换对象并访问私有数据成员吗?

我可以将复制构造函数设为私有并仍然使用默认实现吗

const 和非 const getter:C2248:无法访问类中声明的私有成员

用私有属性替换类中的每个字段是一种不好的做法吗? [复制]

在Java中,如果这样写,为啥私有数据成员可以在类外部访问? [复制]

子类会在后台包含来自超类的私有方法和成员变量吗? [复制]