0

果物クラスがあり、構築時に果物の種類を確認するとします。

var fruitType = {
  "apple": 0,
  "orange": 1
};

fruit = function(name) {
  if (name in fruitType) {
    this.name = name;
  } else {
    throw "wrong fruit type";
  }
};

しかし、オブジェクトの構築後にプロパティが設定されるのを避けることはできません:

var f = new fruit("apple");
f.name = "orange"; // ok
f.name = "cat"; // expecting this does nothing, f.name is still "orange"

チェックを行い、プロパティを変更しないようにする方法は?

4

3 に答える 3

1

プロパティを直接使用するのではなく、getter および setter 関数を使用することから始めます。

var fruitType = {
  "apple": 0,
  "orange": 1
};

var fruit = function(name) {
  this.setName(name);
};

fruit.prototype.getName = function(){
  return this.name;
}

fruit.prototype.setName = function(name){
  if (name in fruitType) {
    this.name = name;
  } else {
    throw "wrong fruit type";
  }
};

直接オーバーライドすることもできますf.nameが、一貫性があり、セッターを使用している限り、問題は発生しません。

var f = new fruit("apple");
f.setName('orange'); // OK
f.setName('toast'); // Throws an error
f.name = 'toast'; // This works, so don't do it!

JSFiddle (ダークナイトに感謝)

それがうまくいかないことが重要な場合は、フルーツ オブジェクトごとに個別の関数を、プライベート スコープの変数f.name = 'toast'と共に使用できます。name

var fruitType = {
  "apple": 0,
  "orange": 1
};

var fruit = function(name) {

  this.getName = function(){
    return name;
  }

  this.setName = function(newName){
    if (newName in fruitType) {
      name = newName;
    } else {
      throw "wrong fruit type";
    }
  };

  this.setName(name);

};

これには、すべてのフルーツが関数の独自のコピーを必要とするという欠点がありますが、name変数を変更する唯一の方法はセッターを使用することであるという利点があります。

var f = new fruit("apple");
f.setName('orange'); // OK
f.setName('toast'); // Throws an error
f.name = 'toast'; // This sets the `name` property to 'toast', but:
f.getName(); // this will still return 'orange'

JSFiddle

于 2013-09-13T07:48:17.133 に答える
1

ゲッターとセッターを使用します。

this.getValue = function(){
    return value;
};

this.setValue = function(val){
    value = val;
};

チェックロジックをセッターに追加します。

于 2013-09-13T07:47:49.877 に答える
0

ありがとう@Paulproのアイデア、これが私のバージョンです:

fruit = function(name) {
  Object.defineProperty(this, "name", {
    get: function() { return this.nameValue; },
    set: function(v) {
      if (v in fruitType) {
        this.nameValue = v;
      }
    }
  });

  if (name in fruitType) {
    this.name = name;
  } else {
    throw "wrong fruit type";
  }
};
于 2013-09-13T09:23:07.823 に答える