2013-05-14 74 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解释我的回答有什么问题 –