web-dev-qa-db-ja.com

情報漏えいのないnodejsのみの環境のES6モジュール/クラスで「実際の」プライベートメソッドを定義する

[〜#〜] real [〜#〜]プライベートメソッド[〜#〜] inside [〜#〜] ES6クラスがないことを知っています。しかし、私は少し遊んでいて、何か良いものを発見しました-多分...

前述したように、オブジェクトのプロパティを公開しないことはできません。しかし、クラスを別々のファイルに分割し、次のようにそれらのクラスをエクスポートするときに、OOPプログラミングのいくらかを達成しようとしました。

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

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

}

// expose class to environment.
export default MyClass;

だから私はクラスをインポートすることができます:

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;

これで、プライベート変数とプライベートメソッドにアクセスできなくなります。

// 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?

exportという言葉でそれらを公開していないので、それらが「プライベート」であるように感じていることは明らかです。私の質問は、このメソッドがプライベート変数とメソッドの作成と見なすことができるかどうかです。そして、私が示した方法で、コードの実行中に他にリークが発生する可能性がある場合はどうなりますか?

よろしく、メガジン


補足:NodeJSのみの環境であるため、ブラウザーのサポートは必要ありません。私はNodeJS v8.1.4を使用しており、npm startスクリプトでbabelを使用しているので、importなしでTypeErrorを使用できます。

この質問は重複していると見なされる可能性があることも承知していますが、これは、この質問がクラス内ではなくクラス外のプライベートプロパティ、変数、メソッドに関するものではないためではありません。

6
Megajin

私の質問は、このメソッドがプライベート変数とメソッドの作成と見なすことができるかどうかです。

はい、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

ここ スコープについての良い説明があります


コメントによるとより多くの情報

複数のクラスインスタンスが「スコープ外」変数を共有するという問題をどのように解決しますか?

この投稿 で@Son JoungHoが説明しているように、 IIFE(即時呼び出し関数式) を使用できます。

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

  class Name {
    constructor() {}

    publicMethod() {
      _privateHello();
    }
  }

  return Name;
})();
5
Grégory NEUT