我正在尝试创建一个具有一系列“slave”属性的全局对象,这些属性派生自同一对象中一个“master”属性的值 - 如下所示:
var x = 5;
var myObj = {
master : 17,
slave1 : this.master + x,
slave2 : (this.master / 2.2) + 1,
slave3 : Math.floor(this.slave2)
//etc.
};
我意识到这是非常错误的,但概念就在那里。我想要做的是更新所有这些'slave'属性,因为myObj.master
已更新。最干净的方法是什么?是否需要通过在myObj.master
更改时触发的某个事件处理程序显式设置每个从属值...?
答案 0 :(得分:4)
如果您不是针对Internet Explorer用户,请尝试使用getter和setter。
var x = 5;
function myObj()
{
this.master = 17;
this.getSlave1 = function() {return this.master + x;},
this.getSlave2 = function() {return (this.master / 2.2) + 1;},
this.getSlave3 = function() {return Math.floor(this.getSlave2());}
}
myObj.prototype = {
get slave1() {
return this.getSlave1();
},
get slave2() {
return this.getSlave2();
},
get slave3() {
return this.getSlave3();
}
};
行动中:
window.onload = function()
{
o = new myObj();
document.write("Master: "+o.master+"</br>");
document.write("Slave 1: "+o.slave1+"</br>");
document.write("Slave 2: "+o.slave2+"</br>");
document.write("Slave 3: "+o.slave3+"</br></br>");
o.master = 42;
document.write("Master: "+o.master+"</br>");
document.write("Slave 1: "+o.slave1+"</br>");
document.write("Slave 2: "+o.slave2+"</br>");
document.write("Slave 3: "+o.slave3+"</br>");
}
产生输出:
Master: 17
Slave 1: 22
Slave 2: 8.727272727272727
Slave 3: 8
Master: 42
Slave 1: 47
Slave 2: 20.09090909090909
Slave 3: 20
此代码将从不在过去,现在或将来的任何版本的Internet Explorer中工作。但是,仍然可以使用getSlaveX()
函数访问从属值。
答案 1 :(得分:2)
你可能最好使用功能。
var x = 5;
var myObj = {
master : 17,
slave1 : function() { return this.master + x },
slave2 : function() { return (this.master / 2.2) + 1 },
slave3 : function() { return Math.floor(this.slave2()); }
//etc.
};
var example = myObj.slave3();
答案 2 :(得分:2)
大卫的答案是一个选项,但是如果你想缓存结果而不是每次重新计算结果,那么反过来一样:
var x = 5;
var myObj = {
setMaster: function(val) {
this.master = val;
this.slave1 = this.master + x;
// ...
}
};
myObj.setMaster(17);
答案 3 :(得分:1)
另一种选择可以是使用构造函数来构建你的对象,例如:
var x = 5;
function MyObj(master) {
this.master = master;
this.slave1 = this.master + x,
this.slave2 = (this.master / 2.2) + 1,
this.slave3 = Math.floor(this.slave2)
}
var myObj = new MyObj(17);
在上面的示例中,我使用master
参数和对x
全局属性的引用,如果您在该范围内没有x
,则还可以提供论证。
您还可以通过几个步骤构建对象:
var myObj = {
master : 17
}, x = 5;
myObj.slave1 = myObj.master + x;
myObj.slave2 = (myObj.master / 2.2) + 1;
myObj.slave3 = Math.floor(myObj.slave2);
答案 4 :(得分:0)
您不希望公开从属设备并允许它们被设置,因为这会删除它们与master的链接。所以他们应该是私人的。
var x = 5;
var MyObject = function() {
var master = 17;
this.setMaster = function(newMaster) {
master = newMaster;
};
this.getMaster = function() {
return master;
};
var slaves = {
slave1 : function() { return master + x },
slave2 : function() { return (master / 2.2) + 1 },
slave3 : function() { return Math.floor(this.slave2()) }
};
this.getSlave = function(slave) {
return slaves[slave]();
};
};
var o = new MyObject();
o.getSlave("slave1"); // 22
o.getSlave("slave3"); // 8
o.setMaster(3);
o.getSlave("slave1"); // 8
o.getSlave("slave3"); // 2
答案 5 :(得分:0)
您可以使用valueOf
和toString
模拟吸气剂,但它有点笨拙。
function makeValueOf(fn) {
return {
valueOf: fn,
toString: fn
};
}
function makeObj(master, x) {
var self = {};
self.master = master;
self.slave1 = makeValueOf(function () { return self.master + x; });
self.slave2 = makeValueOf(function () { return self.master / 2.2 + 1; });
self.slave3 = makeValueOf(function () { return Math.floor(self.slave2); });
return self;
}
var myObj = makeObj(6, 2);
alert(myObj.slave1 + 5); // 13