2011-04-28 104 views
5

您能否提出任何解決方法來實現使用閉包或其他技巧引用變量?javascript如何創建參考

createReference = function() { 
    // TODO: how to implement? 
}; 

var x = 5; 
var refX = createReference(x); // could be any parameters needed to implement the logic 
x = 6; 
alert(refX()); // should alert 6 

什麼有關傳遞上下文第一個參數,並傳遞變量名稱(如串)和後以某種方式評估預定義的上下文參考。這是可行的嗎?

這裏有一個更完整的場景:

createReference = function(context, prop) { 
    return function() { 
     return context[prop]; 
    }; 
}; 

Provider = function() { 
}; 
Provider.prototype.x = 5; 
Provider.prototype.getXRef = function() { 
    return createReference(this, 'x'); 
}; 
Provider.prototype.incrementX = function() { 
    this.x = this.x + 1; 
}; 

var provider = new Provider(); 
var refX = provider.getXRef(); 
provider.incrementX(); 
alert(refX()); 
+1

將來,請不要將您的問題作爲代碼中的嵌入式註釋提出。這使得很難看到這個問題,而且讓人們認爲這不是一個問題。 – Oded 2011-04-28 19:28:42

+0

我很高興我回答了你的問題,但是,在你更新的場景中,爲什麼不直接使用:'Provider.prototype.getXRef = function(){var that = this;返回函數(){return that.x; }; };'這樣你可以避免使用字符串? – brianpeiris 2011-04-28 20:23:08

+0

createReference是通用的方法。那麼在不同的情況下,我只會使用這種通用的方式。關於你的評論:它冷沒有Provider.prototype.getXRef方法,但在其他一些方法可能我想傳遞引用一些其他對象作爲回調參數等...它會更可讀寫createReference(這, 'x')then function(){var that = this;返回函數(){return that.x; }; };在日常使用中。 – 2011-04-28 20:37:36

回答

5

你必須使用變量名的字符串,但我認爲這是接近你永遠可以在javascript:

var createReference = function (context, prop) { 
    return function() { return context[prop]; }; 
}; 

var x = 5; 
var refX = createReference(this, 'x'); 
x = 6; 

alert(refX()); // alerts 6 

編輯:

在你更新的情況下,最好直接使用閉包,以便不必使用變量名稱的字符串:

var createReference = function (context, func) { 
    return function() { return func.call(context); } 
}; 

Provider = function() { 
}; 
Provider.prototype.x = 5; 
Provider.prototype.getXRef = function() { 

    return createReference(this, function() { return this.x; }); 

    // OR if you happen to be running in a 
    // JavaScript 1.8 environment like Firefox 3+, 
    // you can use "expression closures" for more 
    // concise code: 

    // return createReference(this, function() this.x); 
}; 
Provider.prototype.incrementX = function() { 
    this.x = this.x + 1; 
}; 

var provider = new Provider(); 
var refX = provider.getXRef(); 
provider.incrementX(); 
alert(refX()); // alerts 6 
+0

是的,不錯的選擇。但是,javascript不是以save方式保存的,並且名稱誤用時不會出現「編譯時」錯誤,因此我認爲最好使用更短且更易讀的方法(對於我)代碼,而不使用字符串方式。 – 2011-04-28 21:42:45

0

你不能只是促進x做個參考。

+0

使用閉包等的任何解決方法? – 2011-04-28 19:29:49

2

在JavaScript中,您不能通過引用傳遞基元值(數字,字符串等)。但是,您傳遞的每個對象都將始終作爲參考。 (這包括陣列)

要使用例如:

var foo = { x: 5 }; 
var refFoo = foo; 

// foo.x => 5 
// refFoo.x => 5 

foo.x = 6; 

// foo.x => 6 
// refFoo.x => 6 
+0

有沒有辦法用'new Number(4)'做到這一點?這是一個對象。你可以(重新)將它的價值設定爲「保持活力」並讓它通過?像'n =新數字(4); N2 = N; n2.setValue(7); alert(n);' – Rudie 2011-04-28 19:36:39

+0

是的,那將是一個對象。在技​​術上,幾乎所有的JS都是一個對象。但是,標量值(數字,字符串等)不會被引用傳遞,這只是JS的工作方式。 – 2011-04-28 20:04:16

+0

我知道這是一個對象,但是如何更改Number對象的值? '.setValue'不存在,你不能重新分配一個新的對象,因爲你失去了對'n'的引用。不要工作:'n2 = 7;','n2 = new Number(7);','n2.setValue(7);'。前兩個失去參考,第三個不存在。 **如何更改數字對象的值?** – Rudie 2011-04-29 08:02:52

0

只有非標量類型可如引用傳遞,並且將始終作爲引用傳遞:

var reference = {}; 
my_function(reference); 
console.log(reference); // will show property - a property value 

function my_function(my_reference) { 
    my_reference.property = "a property value"; 
} 

var not_a_reference = []; 
my_function(not_a_reference); 
console.log(not_a_reference); // will NOT show 'a value' 

function my_function() { 
    my_reference.push("a value"); 
} 

接近你例如:

function show(value) { 
    alert(value.data); 
} 

var value = { 'data': 5 }; 
show(value); // alerts 5 
value.data = 6; 
show(value); // alerts 6 
0

由於對象始終是靜態引用,因此您可以這樣做:

var o = {}; 
o.x = 5; 
var oRef = o; 
alert(oRef.x); // -> 5 
o.x = 6; 
alert(oRef.x); // -> 6