29

I'm new to js and trying to understand global and private functions. I understand global and local variables. But if I have an html named test.html and a 2 js files named test1.js and test2.js. Now I include the test1.js and test2.js in test.html and call the functions written in test2.js inside test1.js and test.html.

The functions that I have written in test2.js are in this form

function abc(){...}

function pqr(){...} etc.

are these above functions global? If they are , how can I not make them global and still access them in test1.js and test.html?

As I have read global functions or global variables are bad right?

Dai
  • 141,631
  • 28
  • 261
  • 374
ugandajs
  • 291
  • 1
  • 3
  • 3
  • Scope has nothing to do with the fact they are in different JavaScript files. Run a simple test. Put a function in test1 and call it from test2. Does it work? – epascarello Apr 08 '15 at 12:19
  • pretty much exactly the same way as global variables. If you have a var declaration at "top level", then that variable will be a property of the global object - the same with the functions you defined with the function keyword. – doldt Apr 08 '15 at 12:19
  • what do you exactly mean? – ugandajs Apr 08 '15 at 12:19
  • You could add a namespace to `window` and have each file add to that namespace. That would prevent you from polluting `window` with lots of variables which I think is what you're worried about. – Andy Apr 08 '15 at 12:21
  • right. but that namespace would be added to the window object and technically the functions that I've written are still global right? but just that they are under a namespace. Correct? – ugandajs Apr 08 '15 at 12:23
  • That's right, but you won't be flooding global with everything, just one thing. – Andy Apr 08 '15 at 12:29

7 Answers7

31

Everything in JS is bound to containing scope. Therefore, if you define a function directly in file, it will be bound to window object, i.e. it will be global.

To make it "private", you have to create an object, which will contain these functions. You are correct that littering global scope is bad, but you have to put something in global scope to be able to access it, JS libraries do the same and there is no other workaround. But think about what you put in global scope, a single object should be more than enough for your "library".

Example:

MyObject = {
    abc: function(...) {...},
    pqr: function(...) {...}
    // other functions...
}

To call abc for somewhere, be it same file or another file:

MyObject.abc(...);
Marko Gresak
  • 7,950
  • 5
  • 40
  • 46
  • You can make a function private with `var` as well: `var mySuperAwesomeFunction = function() {};` – Jordumus Apr 08 '15 at 12:26
  • yes but if u wont write var in front of abc, then abc is still global and accessible as abc() from other files. Correct? Then whats the point? – ugandajs Apr 08 '15 at 12:26
  • @ugandajs no: the functions `abc` and `pqr` will only be available from within the `MyObject` element if you use this notation. – Jordumus Apr 08 '15 at 12:27
  • 7
    @Jordumus that's not correct at all. Open JS console, write `var x = function() {console.log('x')}` and then try to call `window.x()`. In browsers, `window` is global scope, therefore the function is global. – Marko Gresak Apr 08 '15 at 12:30
  • @ugandajs as @Jordumus said, it's only available in `MyObject` scope, note that it's `abc: function...`, *not* `abc = function...`. You would be correct for the latter case, but that expression is not allowed in objects, it will throw runtime error. – Marko Gresak Apr 08 '15 at 12:33
  • @MarkoGrešak the function is restricted to the file, and you can't call it from another JS-file., right? – Jordumus Apr 08 '15 at 12:33
  • @Jordumus - So you mean it will only be accessible to test.html & not in test1.js? – ugandajs Apr 08 '15 at 12:35
  • @ugandajs, no, it's restricted to `MyObject`, which is globally accessible. Please try my code first. – Marko Gresak Apr 08 '15 at 12:38
  • @Jordumus no, it doesn't matter in which file it is. JavaScript's `var` binds the value to current scope. If you define `var something = ...` directly, without it being in another function, the value will be bound to `window`, i.e. global, scope. – Marko Gresak Apr 08 '15 at 12:43
  • @MarkoGrešak Ok, thank you for correcting me, I won't delete my comments as it would lead to confusion in the thread, but I upvoted your reaction, so others see your comment first. – Jordumus Apr 08 '15 at 12:44
  • @Jordumus not a problem and thanks for the upvote. You learn something new everyday :) – Marko Gresak Apr 08 '15 at 12:45
  • Just to clarify: `var` is bound to current function scope, `let` is bound to block scope. Here's a reference: https://stackoverflow.com/a/11444416/484127 – tutuDajuju Jan 16 '19 at 16:00
15

in test2.js you can write this to make the function global

window.abc = function(){...}

and then in test1.js yo can access it like this

window.parent.abc();

I hope it will help you

Sohaib
  • 675
  • 8
  • 15
8

Anything defined in a file without any sort of wrapper will be bound to the window object. Anything bound to the window object is global.

Example:

//these are global variables
foo = 123;
var ABC = 'school';

//these are "private" variables
test = function(){
  var foo = 123
}

(function(){
  var ABC = 'school';
}).call(this);

Since global variables in every file will be part of the window object, you can access them between files. It is important when creating "private" variables you add var. This says override any global variables in the current "wrapper". If I have a global variable foo and I define it again in a function with var they will be separate.

var foo = 123;
(function(){
  var foo = 987; //this foo is separate from the above foo
}).call(this);

If you do have a "wrapper" and you want to define a global function you can do it like this:

window.foo = 123;
(function(){
  window.foo = 123;
}).call(this);

Both functions will do the same thing.

Personally, I prefer to put everything in a wrapper and only define global variables when I need them using window.

(function(){

  //all code goes here

  //define global variable
  window.foo = 123;

})call(this);
Jon Doe
  • 2,172
  • 1
  • 18
  • 35
6
var SomeName = function() {

    var function1 = function (number) {
        return number+1;
    }

    var anotherFunction = function (number) {
        return number+2;
    }

    return {
        function1: function (number) {
            return function1(number);
        },
        function2: function (number) {
            return anotherFunction(number);
        }
    }
}();

calling

console.log(SomeName.function1(1)); //logs 2

console.log(SomeName.function2(1)); //logs 3
AlexSp3
  • 2,201
  • 2
  • 7
  • 24
fellak
  • 61
  • 1
  • 3
  • 4
    You can also `return { function1: function1, function2: anotherFunction }` and save yourself from repeating the parameters. – FercoCQ Jun 28 '17 at 16:55
5

A modern approach (2020) to using global data is by using a global object literal and define there all your needed logic.

const Website = {
  foo () {
    console.log('foo')
  },
  
  bar () {
    console.log('bar')
  }
}

document.addEventListener('DOMContentLoaded', () => {
  Website.foo()
  Website.bar()
})

If your code is more complex than a couple of lines you will need to separate your code into multiple files and with webpack you merge them together into one file.

import Foo from './js/Foo.js'
import Bar from './js/Bar.js'

// define here another object literal or setup document events.
// webpack will merge all this together into one file
<script src="js/webpack-merged.js"></script>

The reasons you don't want to import individual js files with html is described here. The jist of it is you will have poor performance, so you must bundle all your js.

dreamLo
  • 1,612
  • 12
  • 17
2

If you don't understand why global variables are bad, then why are you trying to avoid them?

Global functions aren't necessarily bad. What's bad is state that anyone and anything and change.

In general since you're new to Javascript, it's fine to start out with global functions spread out across multiple javascript files that you include in your html file via script tags.

As you transition from beginner to intermediate, you will have to look into some "module" solution (I personally recommend RequireJS).

For now though, you can make do with a simpler module pattern:

var T1 = function() {
   return < some module object >
})(); // notice the parenthesis

Google "Javascript module pattern".

Also see this answer.

Community
  • 1
  • 1
hasen
  • 161,647
  • 65
  • 194
  • 231
-2

vos fonctions ne sont pas global si vous faite l'erreur de les incorporé dans par exemple :

$( document ).ready(function() {  
function myglobalfunction() { ... }
});

vous devez retirer

$( document ).ready(function() {

your functions are not global if you make the mistake of embedded them in for example:

$(document) .ready (function () {
function myglobalfunction () {
...
}
});

you must remove

$ (document) .ready (function () {
Darksynx
  • 68
  • 5