2010-11-11 170 views
1

在「本」方面,我正在嘗試做這樣的事情:對象創建

var test = { 
    a: 10, 
    b: 20, 
    c: (this.a+this.b) 
}; 

,但它不工作。我如何從test.c中訪問test.a? 這可能嗎?

回答

5

在指定對象文字的表達式中引用「this」是不可能的。或者做一個下面的行或使用這樣的構造:

function myobj(a,b) { 
    this.a = a; 
    this.b = b; 
    this.c = this.a + this.b; 
} 

var test = new myobj(10,20); 

響應於該方法是更快的,創建與所述對象的構造是更快。這是一個簡單的測試用例比較。 Run it yourself on JSBIN

結果表明,對象創建使用構造VS對象文本幾乎是兩倍的速度:

0.450s:testObjectLiteral

0.506s:testObjectLiteralWithFunction

0.280s:testConstructor

下面是內聯的測試代碼:

// timer function 
function time(scope){ 
    time.scope = time.scope || {}; 
    if(time.scope[scope]) { 
    var duration = (new Date()).getTime()-time.scope[scope]; 
    time.scope[scope] = null; 
    var results = document.getElementById("results"); 
    results.innerHTML = results.innerHTML + '<p>'+(duration/1000).toFixed(3)+'s : '+scope+'</p>'; 
    } else { 
    time.scope[scope] = (new Date()).getTime(); 
    } 
} 

// object creation function with constructor 
function myobj(a,b) { 
    this.a = a; 
    this.b = b; 
    this.c = this.a + this.b; 
} 

function testConstructor(iterations) { 
    var objs = new Array(iterations); 
    for(i=0;i<iterations;i++) { 
    objs[i] = new myobj(i,i+1); 
    } 
    return objs; 
} 

function testObjectLiteralWithFunction(iterations) { 
    var objs = new Array(iterations); 
    for(i=0;i<iterations;i++) { 
    objs[i] = { 
     a: i, 
     b: i+1, 
     c: function() { 
     return this.a + this.b; 
     } 
    }; 
    } 
    return objs; 
} 


function testObjectLiteral(iterations) { 
    var objs = new Array(iterations); 
    for(i=0;i<iterations;i++) { 
    var item = { 
     a: i, 
     b: i+1 
    }; 
    item.c = item.a + item.b; 
    objs[i] = item; 
    } 
    return objs; 
} 

var ITERATIONS = 1000000; 
time("testObjectLiteral"); 
testObjectLiteral(ITERATIONS); 
time("testObjectLiteral"); 

time("testObjectLiteralWithFunction"); 
testObjectLiteralWithFunction(ITERATIONS); 
time("testObjectLiteralWithFunction"); 

time("testConstructor"); 
testConstructor(ITERATIONS); 
time("testConstructor"); 

+0

+1爲OOP解決方案。 – zzzzBov 2010-11-11 18:18:19

+0

感謝您的幫助。另一個問題:這種方式是否比「var myObj = {a:4,b:5 ....}」更快地聲明一個對象;「一? – 2010-11-12 00:23:50

+0

@dizzy_fingers查看我添加到我的答案中的性能測試用例 – mbrevoort 2010-11-12 18:34:57

2

在對象文字中不可能這樣做,因爲this不能用於引用尚未創建的對象。你最好的選擇是將c財產在單獨的步驟分配:

var test = { 
    a: 10, 
    b: 20 
}; 

test.c = test.a + test.b; 
0

聲明對象文字時,你根本就做不到這一點,你可以做的最接近的是:

var test = { 
    a: 10, 
    b: 20 
}; 
test.c = test.a + test.b; 

在你背景this是指你任何父上下文中,而不是test對象......即使它沒有,你不能聲明成員一樣,例如這也是無效:

var test = { a: 10, b: 20, test.c: test.a + test.b }; 

...因爲test,ab尚未定義,因爲它是一個尚未完成的單個語句。

-2

爲什麼不能使C的功能,以便它總是返回A + B的當前值?

var test = { 
    a: 5, 
    b: 1, 
    c: function() { 
     return this.a + this.b; 
    } 
} 
+0

感謝您的建議。但是性能問題呢?是否在c:聲明之後添加了一個閉包額外的開銷? – 2010-11-12 00:25:09

+0

那麼我會想象如此 - 每次調用c()時,它都在評估a + b,而不是簡單地檢索變量的值。但是,根據您的情況,這種差異可能可以忽略不計。如果您正在執行的加法操作涉及大量值,並且/或者您正在引用c()很多次,則最好在初始化時只進行一次該計算,在這種情況下,mbrevoort的解決方案低於可能更有用。最終歸結爲您的情況,以及在執行期間a/b是否會發生變化。 – 2010-11-12 10:29:55

+0

-1這個答案是否正確? – gath 2010-11-19 12:21:06