6
\$\begingroup\$

I have a getValue function which just grabs some numbers from an HTML page.

How can I access those variables in later functions without passing them down the entire chain of functions? As they sit within a function they are not global?

When I call the addition function, it will need to access the variables in the getValue function.

In Java, I would have used a separate class with a normal getter and setter pattern but unsure how to replicate something similar.

I feel like I am missing a key JavaScript concept here.

    function getValue() {
    var decimal = parseInt(parent.document.getElementById('CF_9813416').value);
    var a = parseFloat(parent.document.getElementById('CF_9814331').value);
    var b = parseFloat(parent.document.getElementById('CF_9814407').value);
    var c = parseFloat(parent.document.getElementById('CF_9814615').value);
    }

    function radioButtons() {

        for (var i = 0; i < parent.document.Form1.CF_9813571.length; i++) {
            if (parent.document.Form1.CF_9813571[i].checked) {
                var sign = parent.document.Form1.CF_9813571[i].value;
            }
        }
        radioResult(sign);
    }

    function radioResult(sign) {

        if (sign == '9813524') {
            addition();
        } else if (sign == '9813527') {
            subtraction();
        } else if (sign == '9813530') {
            multiplication();
        } else devision();
    }

    function addition() {

        result = a + b + c;
        writeValue(result, decimal);
    }

    function subtraction() {

        result = a - b - c;
        writeValue(result, decimal);
    }

    function multiplication() {

        result = a * b * c;
        writeValue(result, decimal);
    }

    function devision() {

        result = a / b / c;
        writeValue(result, decimal);
    }

    function writeValue(result, decimal) {
        parent.document.getElementById('CF_9814616').value = result.toFixed(0);
        parent.document.getElementById('CF_9814617').value = result.toFixed(decimal);
    }
</script>
\$\endgroup\$

3 Answers 3

4
\$\begingroup\$

Yes, you are right, decimal, a, b and c are not accessible by other functions because they are local to getValue(). To make them global, you need to declare them outside of your function, like this:

Solution #1

var decimal; 
var a;
var b;
var c;

function getValue(){
 decimal = // assign decimal
 a = // assign a
 // assign rest of the variables
}

function useVariables(){ 
   return a + b + c;
}

Using global variables, however, is considered a bad practice so I would move onto another solution.

Solution #2

Have 'getter functions' for each of your variables. Instead of having getValue(), have getDecimal(), getA(), getB() and getC() functions (you might consider giving these variables more meaningful names). Your code would turn into something like this:

function getA(){
  return parseFloat(parent.document.getElementById('CF_9814331').value);
}

// functions for getB() and getC()

function useVariables(){
  return getA() + getB() + getC();
}

This is a more acceptable solution because you delay getting the variables until you need them and you also do not have global variables. If the values change you get the updated values as well without having to call getValue() again to 'refresh' your data.

\$\endgroup\$
1
  • \$\begingroup\$ Awesome, thank you very much for the response. Solution #2 was what I was thinking of doing prior to posting. Unsure why I decided not to in the first place, since you are correct and it does make the most sense ;) \$\endgroup\$ May 10, 2012 at 0:15
4
\$\begingroup\$

To improve on c_maker's answer, you should enclose the entire thing in a closure to avoid cluttering the global namespace:

(function (wnd, undefined) {
    var decimal; 
    var a;
    var b;
    var c;

    function getValue(){
        decimal = // assign decimal
        a = // assign a
        // assign rest of the variables
    }

    function useVariables(){ 
        return a + b + c;
    }

    // Anything that needs to be in scope outside of the closure can be
    // assigned to wnd.
    wnd.getValues = getValues;

} (window));

This type of construct is known as an IIFE

\$\endgroup\$
1
\$\begingroup\$

You really miss some JavaScript keypoints. JavaScript just has function scope and doesn't has any other block scope.

function radioButtons() {

    for (var i = 0; i < parent.document.Form1.CF_9813571.length; i++) {
        if (parent.document.Form1.CF_9813571[i].checked) {
            var sign = parent.document.Form1.CF_9813571[i].value;
        }
    }
    radioResult(sign);
}

Check your function. You try to define variable 'sign' in the if block, then you use it. That is really bad practice. When I saw this code, I had no idea why the variable can be used even it was out of the scope. So the best practice is put all variable defines at the top of the function.

Don't use global variables; there are lots of ways to ignore it.

  • Use anonymous functions
  • Arrange your function to object
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.