2013-05-14 75 views
3

如果我有:變量範圍和共享信息,而全局變量

function firstFunction(){ 
    var counter = 0; 
    secondFunction(); 
    secondFunction(); 
    secondFunction(); 
    secondFunction(); 
} 
function secondFunction(){ 
    counter++; 
} 

我得到因變量的局部範圍的錯誤,但怎麼回事,我該做這樣的事情,而不使用全局變量?

+1

傳遞參數? –

回答

7

一種方法是使用閉包:

(function() { 
    var counter = 0; 

    function firstFunction() { 
     secondFunction(); 
     secondFunction(); 
     secondFunction(); 
     secondFunction(); 
    } 

    function secondFunction() { 
     counter++; 
    } 
})(); 

另外,還可以在counter值傳遞給secondFunction,像這樣:

function firstFunction() { 
    var counter = 0; 
    counter = secondFunction(counter); 
    counter = secondFunction(counter); 
    counter = secondFunction(counter); 
    counter = secondFunction(counter); 
} 

function secondFunction(counter) { 
    return ++counter; 
} 
+0

這很酷,我仍然可以從我的代碼中的其他位置調用firstFunction()嗎? – dezman

+1

只要「其他地方」在關閉範圍內,是的。如果你想從閉包之外調用該函數,可以在閉包的末尾加上這一行:'window.firstFunction = firstFunction;' –

+0

只要「其他地方」在範圍內,是否存在閉包。 –

1

使用對象通過引用

計數器通
function firstFunction() { 

     var myObj = new Object(); 
     myObj.counter = 0; 

     secondFunction(myObj); 
     secondFunction(myObj); 
     secondFunction(myObj); 
     secondFunction(myObj); 

    } 

    function secondFunction(obj) { 
     obj.counter++; 
    } 
+0

你不需要使用一個對象來傳遞'counter'。 –

+1

@ElliotBonneville是不是隻傳遞計數器,通過值傳遞它,並且變化不會在函數之外持續存在? –

+0

是的,沒錯。爲了解決這個問題,你可以返回'計數器'。但是,我必須說,我喜歡這種代碼模式。我以前沒有見過。但是,我會建議使用對象字面值來代替:'var counterHolder = {counter:0};' –

1

由於原始類型(如整數和str英格斯)在JavaScript是按值傳遞,但對象是通過引用傳遞,你需要使用一個對象:

// passing primitive type 
var counter = 0; 
for (var i = 0; i < 4; ++i) { 
    secondFunction(counter); 
} 
alert(counter); // 0 
function secondFunction(counter) { 
    counter++; 
} 

// passing object 
var obj = { counter: 0 } 
for (var i = 0; i < 4; ++i) { 
    secondFunction(obj); 
} 
alert(obj.counter); // 4 
function secondFunction(obj) { 
    obj.counter++; 
} 

http://jsfiddle.net/MpVqQ/2/

這樣就可以達到你想要的東西,而無需使用全局變量。

+2

_everything_在JS中通過值傳遞,沒有變量持有對象。變量'obj'的值不是對象字面值,它的值是一個引用。另外:函數是對象,每個函數調用都會創建一個調用對象(包含範圍),這是一種更好,更安全和更可控的方式來開展業務99.99%的時間 –

+2

在您的示例中,您忘記*傳遞*對象,你也可以使用一個原始變量:-) – Bergi

+0

是的,真的,修復它:) – konnigun

0

作爲補充埃利奧特巴納維亞的答案,你也可以這樣做:

var firstFunction = (function() 
{ 
    var counter = 0, 
    secondFunction = function 
    { 
     counter++; 
    }; 
    return function() 
    { 
     counter = 0;//initialize counter to 0 
     secondFunction(); 
     return counter; 
    }; 
}; 
console.log(firstFunction());//logs 1, because counter was set to 1 and returned 

這一切變得有點多,但谷歌「的JavaScript模塊模式」和調查一下。你很快就會發現什麼使這個代碼打勾:

var counterModule = (function() 
{ 
    var counter = 0, 
    secondFunction = function 
    { 
     counter++; 
    }, 
    firstFunction = function() 
    { 
     counter = 0;//initialize counter to 0 
     secondFunction(); 
    }, 
    getCounter = function() 
    { 
     return counter; 
    } 
    setCounter = function(val) 
    { 
     counter = +(val); 
    }; 
    return {firstFunction: firstFunction, 
      getCounter: getCounter, 
      setCounter: setCounter}; 
}; 
console.log(counterModule.firstFunction());//undefined 
console.log(counterModule.getCounter());//1 
console.log(counterModule.secondFunction());//ERROR 

這是所有關於某些閉包變量的曝光......堅持下去的工作,這是需要理解的重要模式,我答應!

+0

爲什麼倒票...一如既往:我不介意,只要DV'er解釋我的回答有什麼問題 –