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特性)的浏览器中进行。