Ashish Agarwal
Ashish Agarwal

Reputation: 14925

Calling nested functions in javascript

I have a javascript file named js/jsClasses.js which is relative to to the index.html file.

This file has some nested functions. Here's the code -

function JSClass(){ //notice the capital J which though doesn't change execution is a convention indicating a class constructor
var langSetting;
this.setLanguage = function(){
    langSetting = "en-GB";
    console.log(langSetting);
}
this.getLanguage = function(){
    return langSetting;
}

}

I need to set the value of the variable langSetting in index.html. This will be the global variable and in all the subsequent pages, I need to access the value of langSetting and load the page in the corresponding language.

At the moment, this is how I am trying to access the js/jsClasses.js file from index.html

<html>
    <script src="js/jsClass.js">
        var object1 = new JSClass();
        object1.setLanguage();
        object1.getLanguage();
    </script>



</html>

When I click the button, nothing happens. Can someone please help ?

Upvotes: 0

Views: 2840

Answers (1)

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

There are two ways to solve this, a bad and common one and a good one,

The bad one is to remove the var key word from langSetting which would make it langSetting a global varaible.

The good one is to have JSClass return langSetting or more broadly an object revealing what it, as a module is willing to reveal, this is called the revealing module pattern, here is an excellent book chapter on it by Google developer Addy Osmani

Here is a good solution in your case:

var jsClass= function(){


    var langSetting = "en"; // this is javascript's version of a private variable, it is 'closed' in your jsClass

    var getLanguage = function(){
        return langSetting;
    }

    var setLanguage = function(){
        navigator.globalization.getPreferredLanguage(function (language){
            langSetting = language.value; //set the local variable
            console.log(langSetting);
        }, function(){
            console.log("there was an error");
        });
    }
    return {
        getLanguage:getLanguage,
        setLanguage:setLanguage
    };
}

Then in your code you can do

var obj = new jsClass(); // is exactly the same as var obj = jsClass , when functions return objects it doesn't matter if you use the 'new' keyword
obj.getLanguage(); //returns en

Another solution would be to use the constructor pattern. Some consider the constructor pattern as a mistake made to implement java developers migrating to javascript although it is widely used in the industry and in a lot of libraries. This would look the following way:

function JSClass(){ //notice the capital J which though doesn't change execution is a convention indicating a class constructor
    var langSetting;
    this.setLanguage = function(){
        //setter code here
    }
    this.getLanguage = function(){
        //getter code here
    }
}

and then use the new keyword, it would look like:

var myClass = new JSClass();
myClass.getLanguage();//getter result

Also, note I'm noticing that you're using Apache Cordova API for globalization, please note that makes setLanguage asynchronous, so you might want to have it accept a callback parameter which means you get to 'hook' on when it completes. See This stackoverflow question for more details on callbacks and how to use them.

Upvotes: 2

Related Questions