8

私が見たクラスパターンは、次のようなものになります。

class Foo {
    constructor(x, y, z) {
      this._x = x;
      this._y = y;
      this._z = z;
    }

    get x() {
      return this._x;
    }
    set x(value) {
      //I acctually do some stuff here
      this._x = value;
    }

    get y() {
      return this._y;
    }
    set y(value) {
      //I acctually do some stuff here
      this._y = value;
    }

    get z() {
      return this._z;
    }
    set z(value) {
      //I acctually do some stuff here
      this._z = value;
    }
}

console.log(new Foo('x', 'y', 'z'))実行出力:

Foo { _x: 'x', _y: 'y', _z: 'z' }

console.log(JSON.stringify(new Foo('x', 'y', 'z')))実行出力:

{"_x":"x","_y":"y","_z":"z"}

これにより、アンダースコアのプレフィックス付きフィールドが得られますが、それを目指していませんでした。フィールドにアンダースコアのプレフィックスを持たないようにするにはどうすればよいですかinstance.prop

4

4 に答える 4

15

toJSONの出力を調整するメソッドを追加できますJSON.stringify

class Foo {
    constructor(x, y, z) {
      this._x = x;
      this._y = y;
      this._z = z;
    }

    get x() {
      return this._x;
    }
    set x(value) {
      this._x = value;
    }

    get y() {
      return this._y;
    }
    set y(value) {
      this._y = value;
    }

    get z() {
      return this._z;
    }
    set z(value) {
      this._z = value;
    }

    toJSON() {
      return {
        x: this._x,
        y: this._y,
        z: this._z
      };
    }
}

var foo = new Foo('x', 'y', 'z');
console.log(JSON.stringify(foo));

出力:"{"x":"x","y":"y","z":"z"}"

于 2016-11-03T17:29:38.763 に答える
5

問題が本当にアンダースコアのみである場合は、次のように、get/set メソッドが PascalCase を使用し、メンバー変数が camelCase を使用する C# のプロパティに似た命名規則を使用してみてください。

class Foo {
    constructor(x, y, z) {
      this.x = x;
      this.y = y;
      this.z = z;
    }

    get X() {
      return this.x;
    }
    set X(value) {
      this.x = value;
    }

    get Y() {
      return this.y;
    }
    set Y(value) {
      this.y = value;
    }

    get Z() {
      return this.z;
    }
    set Z(value) {
      this.z = value;
    }
}

最終的に、ECMAScript 6 でのオブジェクトの動作方法により、メンバー変数と get/set メソッドの名前を 100% 同じにする方法はありません。実際のところ、これがアンダースコア形式の使用が非常に一般的である理由です。アンダースコアは、コードを見ている人に、プロパティが「プライベート」であることを意図していることを示しています。ECMAScript 6 では、プライベート メンバーの概念は実際には存在しません。

于 2016-11-03T17:27:24.633 に答える
2

アンダースコア プロパティをスキップする場合は、それらを列挙不可として定義します。

class Foo {
  constructor(x, y, z) {
    this._x = x;
    this._y = y;
    this._z = z;
    Object.defineProperties(this, {
      _x: {enumerable: false},
      _y: {enumerable: false},
      _z: {enumerable: false}
    });
  }
  get x() { return this._x; }
  set x(value) { this._x = value; }
  get y() { return this._y; }
  set y(value) { this._y = value; }
  get z() { return this._z; }
  set z(value) { this._z = value; }
}
console.log(JSON.stringify(new Foo('x', 'y', 'z')))

下線付きのプロパティの代わりに記号を考慮することもできます。

class Foo {
  constructor(x, y, z) {
    this[Foo.x] = x;
    this[Foo.y] = y;
    this[Foo.z] = z;
  }
  get x() { return this[Foo.x];  }
  set x(value) { this[Foo.x] = value; }
  get y() { return this[Foo.y]; }
  set y(value) { this[Foo.y] = value; }
  get z() { return this[Foo.z]; }
  set z(value) { this[Foo.z] = value; }
}
Foo.x = Symbol('x');
Foo.y = Symbol('y');
Foo.z = Symbol('z');
console.log(JSON.stringify(new Foo('x', 'y', 'z')))

于 2016-11-03T17:33:29.997 に答える
0

あなたが言ったようtoJSONに、すべてのクラスでの使用を避けたいと思っていました(ただし、使用toJSONは「正しい」ことだと思います)。

Javascript を使用すると奇妙なことができますが、少なくとも、囲まれた関数スコープで制御できます。

正規表現は洗練されていると思いますが、アイデアを示したかっただけで、きれいではありませんが、うまくいくはずです。

class Foo {
  constructor(x, y, z) {
    this._x = x;
    this._y = y;
    this._z = z;
  }

  get x() {
    return this._x;
  }
  set x(value) {
    //I acctually do some stuff here
    this._x = value;
  }

  get y() {
    return this._y;
  }
  set y(value) {
    //I acctually do some stuff here
    this._y = value;
  }

  get z() {
    return this._z;
  }
  set z(value) {
    //I acctually do some stuff here
    this._z = value;
  }
}

var originalJSON = JSON;

var foo = new Foo('x', 'y', 'z');

(function () {

  var JSON = {
    stringify: function (obj) {
      var json = originalJSON.stringify(obj);
      return json.replace(/"_+(\w+)":/g, '"$1":');
    },
    parse: function(str) {
      return originalJSON.parse(str.replace(/"(\w+)":/g, '"_$1":'));
    }
  };

  console.log('Weird hack');

  var r = JSON.stringify(foo);    
  console.log('stringify');
  console.log(r);

  console.log('parse');
  console.log(JSON.parse(r));
}).call();

console.log('\nBack to normal');

var r = JSON.stringify(foo);
console.log('stringify');
console.log(r);

console.log('parse');
console.log(JSON.parse(r));

出力:

Weird hack
stringify
{"x":"x","y":"y","z":"z"}
parse
{ _x: 'x', _y: 'y', _z: 'z' }
Back to normal
stringify
{"_x":"x","_y":"y","_z":"z"}
parse
{ _x: 'x', _y: 'y', _z: 'z' }
于 2016-11-04T14:22:27.660 に答える