在仅nodejs的环境中的ES6模块/类中定义“真实”私有方法,而不会发生任何信息泄漏

Meg*_*jin 6 javascript node.js ecmascript-6 es6-class es6-modules

我知道INSIDE ES6类中没有REAL私有方法。但是我在玩了一会儿,发现了一些好东西-也许...

正如我提到的,不可能不公开对象的属性。但是,当我将类划分为单独的文件,然后将这些类导出时,我试图实现某种OOP编程:

class MyClass {
  constructor() {
    /**
     * Initialize stuff...
     */
  }

  myMethod() {
    /**
     * Do public stuff...
     */
  }

}

// expose class to environment.
export default MyClass;
Run Code Online (Sandbox Code Playgroud)

所以我可以导入该类:

import MyClass from './MyClass.js';

当然myMethod可以从导入该模块的任何其他文件访问。既然我需要只能由该类访问的变量和函数,我已经尝试过了:

// private variable outside of class scope but still accessible.
let possiblePrivateVariable = 'am I a private variable?';

class MyClass {
  constructor() {
    /**
    * Initialize stuff...
    */
  }

  myMethod() {
    // run private method.
    console.log(_possiblePrivateMethod());
    // show private variable.
    console.log(possiblePrivateVariable);
  }

}

// private function outside of class scope but still accessible.
function _possiblePrivateMethod() {
  return 'am I a private method?';
}

// expose class to environment.
export default MyClass;
Run Code Online (Sandbox Code Playgroud)

现在,您无法访问私有变量和私有方法:

// Import class to newFile.js and use it.
import MyClass from './MyClass.js';

const exposedClass = new MyClass();
exposedClass.possiblePrivateVariable;   // -> undefined.
exposedClass._possiblePrivateMethod();  // -> undefined.
exposedClass. myMethod();               // -> logs: am I a private method?
                                        //          am I a private variable?
Run Code Online (Sandbox Code Playgroud)

显然,那些人感觉像在“私下里”,因为我没有把它们暴露给他们export。我的问题是,是否可以考虑使用此方法创建私有变量和方法?如果我显示的方法在运行代码时还有其他可能的泄漏?

此致Megajin


旁注:我不需要浏览器支持,因为它是仅NodeJS的环境。我在脚本中使用NodeJS v8.1.4和使用babel,npm start因此可以import不使用任何脚本TypeError。

我还应该提到,我知道这个问题可以看作是重复的问题,但这并不是因为这个问题不是关于类内部而是类外部的私有属性,变量和方法的。

Gré*_*EUT 5

我的问题是,是否可以考虑使用此方法创建私有变量和方法?

是的,这是解决ES6 / 7/8不处理类隐私问题的实际可行解决方案。

如果我显示的方法在运行代码时还有其他可能的泄漏?

快速回答:无泄漏

详细答案:

在您的私有函数系统中,使函数私有化的原因是,在javascript中,函数的作用域是由其定义位置定义的。您的文件。

如果不将函数导出到文件外部,则无法访问它。就像您无法在以下主流示例中访问该函数:

function toto() {
 const tmpToto = () => console.log('Hello');

 // I can access tmpToto from here
 tmpToto();

 return false;
}

// I cannot access tmpToto from here
Run Code Online (Sandbox Code Playgroud)

在这里,您对范围有了很好的解释


根据评论更多信息

您将如何解决多个类实例将共享“超出范围”变量的问题?

您可以按照@Son JoungHo在本文中所述使用IIFE(立即调用的函数表达式)。

let Name = (function() {
  const _privateHello = function() {}

  class Name {
    constructor() {}

    publicMethod() {
      _privateHello();
    }
  }

  return Name;
})();
Run Code Online (Sandbox Code Playgroud)