2012-07-25 35 views
1

我正在使用closure來隱私。 我不明白爲什麼以及如何從封閉外部改變局部變量。從閉包變化的局部變量。這是一個JavaScript錯誤或我做錯了什麼?

我寫了一個腳本給你解釋問題。

var MyAjax=(function(){ 
    //Create a local variable for privacy 
    var _opts={ 
     cache:true 
    } 
    ,getDefaultOptions=function(){ 
     return _opts 
    }; 

    //return only getDefaultOptions function 
    return { 
    getDefaultOptions:getDefaultOptions 
    } 
})() 


//I am merging new ajax options with default options. 
var defaults=MyAjax.getDefaultOptions(); 
var reqOptions= $.extend(defaults,{cache:false}); 

// I am getting expected result 
console.log("extended var",reqOptions) //{cache:false} 

// I am getting non expected result 
// I should get {cache:true} but I am getting { cache:false } 
console.log("defaults",MyAjax.getDefaultOptions()) //{cache:false} 

爲什麼會發生這種情況?

+0

$ .extend用false覆蓋'defaults.cache',這就是extend的作用。 – jbabey 2012-07-25 12:42:26

+0

變更默認變量normal.But我再次調用MyAjax.getDefaultOptions()但將緩存返回爲false。 – 2012-07-25 12:50:49

+1

「JavaScript總是按值傳遞,但是當一個變量引用一個對象(包括數組)時,」值「是對該對象的引用。」 http://stackoverflow.com/questions/6605640/javascript-by-reference-vs-by-value – jbabey 2012-07-25 13:03:23

回答

1

$.extend()函數修改第一個參數。如果你不想這樣做,請執行以下操作:

var reqOptions = $.extend({}, defaults, {cache: false}); 

詳細說明:傳遞對象的引用作爲第一個參數。儘管它是該閉包的私有變量,但getter函數已經返回了對它的引用,所以它是這樣「可見」的。 jQuery函數是這樣寫的,它總是直接更新作爲第一個參數傳遞的對象。因此,爲了確保不要更改該對象,只需傳入新創建的對象作爲第一個參數。

+0

閉包返回只包含getDefaultOptions函數的json對象。如何訪問_opts並更改它??看到封閉的變量? – 2012-07-25 12:49:25

+0

您的「getDefaultOptions」函數返回對該「_opts」對象的引用。通過返回對象的引用,它允許外部代碼修改對象;這就是對象引用的工作方式。外部代碼不能以任何其他方式訪問「_opts」,因爲它是私有的,但是一旦公開引用,其他任何代碼都可以像處理其他對象一樣操作對象。 – Pointy 2012-07-25 12:57:05

+0

Ok.If默認引用_opts的變量,爲什麼我沒有得到與'var1 = true; VAR2 = VAR1; VAR2 = FALSE; console.log(var2)'?什麼是錯誤?它不一樣嗎'var1 = true;和var1 = getTrue();'這與PHP中使用&字符相同? – 2012-07-25 13:16:22

相關問題