昨天,我发布了prototypal inheritance and constructors。我最终确定了一种方法,可以使代码保持整洁,并以可能对性能产生轻微影响为代价而保留原型:
function Card(value) {
// setValue is a public instance method
this.setValue = function (val) {
if (!range[val]) {
val = drawRandom();
}
// value is a public instance variable
this.value = val;
return val;
};
this.setValue(value);
}
然而,这种方法的问题在于,每当我想设置Card实例的值以获得验证时,我都必须调用setValue方法。我想做的是使用自定义setter方法。这是我到目前为止所做的:
function Card(val) {
// value is a private instance variable
var value;
// This is a private instance method
// It's also self-invoking, but that's beside the point
(function (x) {
if (!range[x]) {
x = drawRandom();
}
value = x;
}(val));
this.__defineGetter__("value", function () {
return value;
});
// Some code duplication
this.__defineSetter__("value", function (x) {
if (!range[x]) {
return false;
}
value = x;
return x;
});
}
这很有效。调用var card = new Card()
会为我提供一个具有随机值的实例,并且调用card.value = null
会失败,因为它超出了范围。
我的问题,除了它显然更长的事实,似乎我复制了一些代码。如果setter方法与构造函数一起调用会很好。这样,我可以消除整个自我调用的私有实例方法。
答案 0 :(得分:2)
函数是Javascript中的第一类对象,所以你可以完全做这样的事情来消除重复:
function setter (x) {
if (!range[x]) {
return false;
}
return x;
}
(function (x) {
value = setter(x);
if (!value) {
value = drawRandom();
}
}(val));
this.__defineGetter__("value", function () {
return value;
});
// Some code duplication
this.__defineSetter__("value", setter);
答案 1 :(得分:1)
首先,您应始终将value
设置为obj.value = newValue
,甚至在内部,因为它会调用您的验证。在构造函数中意味着:
this.value = val;
但是如果你在之前这样做就行不通知了setter和getter。所以在之后移动,以便setter函数在设置时就存在。
这里的工作示例:http://jsfiddle.net/8tCjm/4/
var drawRandom = function () {
return Math.floor(Math.random() * 3) + 1;
};
var range = {
1: 'Ace',
2: 'Two',
3: 'Three'
};
function Card(val) {
var value;
this.__defineGetter__('value', function () {
return value;
});
this.__defineSetter__('value', function (x) {
if (range[x]) {
value = x;
} else {
value = drawRandom();
}
return value;
});
this.value = val;
};
console.log(new Card(1).value); // 1
console.log(new Card(2).value); // 2
console.log(new Card(3).value); // 3
console.log(new Card(987).value); // not 987 (1-3)