3

If I have:

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

I get an error because of the local scope of the variable, but how else am I to do something like this without using global variables?

4

4 回答 4

7

One way is to use a closure:

(function() {
    var counter = 0;

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

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

Alternately, you could pass in the value of counter to secondFunction, like this:

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

function secondFunction(counter) {
    return ++counter;
}
于 2013-05-14T21:50:51.407 回答
1

Use Object to pass counter by reference

   function firstFunction() {

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

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

    }

    function secondFunction(obj) {
        obj.counter++;
    }
于 2013-05-14T21:56:37.657 回答
1

Since primitive types (such as integers and strings) in javascript are passed by value, but objects are passed by reference, you need to use an object:

// 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/

This way you can achieve what you want without using global variables.

于 2013-05-14T22:02:28.383 回答
0

As an addition to Elliot Bonneville's answer, you can also do this:

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

This is all getting a bit much, but google "JavaScript module pattern" and look into it. You'll soon find out what makes this code tick:

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

It's all about exposure of certain closure variables... Keep working at it, this is an important pattern to understand, I promise!

于 2013-05-14T22:09:33.867 回答