Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 设置属性时如何检查值是否有效_Javascript_Oop - Fatal编程技术网

Javascript 设置属性时如何检查值是否有效

Javascript 设置属性时如何检查值是否有效,javascript,oop,Javascript,Oop,假设我有一个水果类,并在构建时检查水果类型: 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

假设我有一个水果类,并在构建时检查水果类型:

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"

如何进行检查并保持属性不变?

使用getter和setter:

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

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

将检查逻辑添加到setter

首先使用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
,但只要您保持一致并使用setter,就不会遇到问题

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!
(感谢黑暗骑士)

如果重要的是
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
变量的唯一方法是使用setter:

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'

谢谢@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";
  }
};

也许这个问题会对你有所帮助:希望你不介意,我只是在你的答案中为你的代码添加了小提琴。@TheDarkKnight我不介意,但我当时正在编辑我的文章,所以它没有通过。再次添加了小提琴。谢谢。但是针对我的代码的测试用例是检查
f.name=x
,getter/setter选项不能满足测试用例的要求。如果你不能修改你的测试用例,你仍然可以做你想做的事情,但只能在支持defineProperty(ES5特性)的浏览器中进行。