2010-09-18 129 views
0

我试图创建一个全局对象有一系列从一个“主”财产在同一个对象的值获得“奴隶”性质 - 是这样的:与内部参考性JavaScript对象

var x = 5; 
var myObj = { 
    master : 17, 
    slave1 : this.master + x, 
    slave2 : (this.master/2.2) + 1, 
    slave3 : Math.floor(this.slave2) 
    //etc. 
}; 

我意识到这是可怕的错误,但概念是存在的。我想要做的是将所有这些“奴隶”属性更新为myObj.master已更新。最干净的方法是什么?是否需要通过某个事件处理函数明确设置每个从属值,当myObj.master被更改时触发?...?

回答

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

大卫的回答是一种选择,但如果你希望缓存的结果,而不是每次都重新计算它们的,做到这一点反过来:

var x = 5; 
var myObj = { 
    setMaster: function(val) { 
     this.master = val; 
     this.slave1 = this.master + x; 
     // ... 
    } 
}; 

myObj.setMaster(17); 
+0

如果你打算采取这种方法,我宁愿将主属性作为私有成员,所以不能直接设置,导致从属属性错误。你必须用构造函数替换文字对象符号。 – lincolnk 2010-09-19 01:05:21

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

如果您没有针对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()函数访问。

+0

是的,getters正是OP想要的 – user187291 2010-09-19 02:44:05

+2

我觉得这很容易出错。你有两个地方的公式,并且可以在不更改主人的情况下更改奴隶。 – mangoDrunk 2010-09-19 03:25:48

+0

@mangoDrunk:好点,我更新了代码,只使用getters检索slave值,使它们只读,并且使得它只能输入一次。 – 2010-09-19 04:02:00

0

你不想公开奴隶并且允许他们被设置,因为那会消除他们与主人的联系。所以他们应该是私人的。

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 
0

你可以模拟使用valueOftoString干将,但它是一个有点笨拙。

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