2010-09-18 101 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