2

I have the following piece of code on my page:

<script src="/Assets/JavaScripts/myJavaScript.js" type="text/javascript"></script>

<script type="text/javascript">

     testAlert();

</script>

And in myJavaScript.js I have the following:

(function () {
     function testAlert() {
          alert('test alert');
     }
})();

It's not calling testAlert. Not sure what I am doing wrong here? I'm trying to avoid global variables and methods. I did something similiar in jQuery and it worked, it just required a $ at the start of the external file. Can somebody please explain what I am doing wrong here and how to make sure I follow best practices?

Brendan
  • 1,853
  • 11
  • 18
Brendan Vogt
  • 25,678
  • 37
  • 146
  • 234

4 Answers4

2

I put your code in my environment and checked, I got error in mozila error console. So, Please check it there. you should put only below javascript function in myjavascript.js file.

function testAlert() {
    alert('test alert');
}
sikender
  • 5,883
  • 7
  • 42
  • 80
  • Thanks, but what is the (function () {})(); part? – Brendan Vogt Oct 11 '11 at 05:08
  • @Brendan: Basically, it creates a function and runs it immediately. In your case, and in the case of jQuery plugins (which are usually written like `(function($) { ...... })(jQuery);`, it (1) makes pretty sure that jQuery is available as `$` (even if it's in no-conflict mode, which makes `$` not mean `jQuery` anymore), and (2) creates a space where you can stick private global stuff, thanks to the spiff of closures. – cHao Oct 11 '11 at 05:14
1

Your function in the js-file isn't returning anything. To avoid global variables you could create one global namespace (-like) variable:

var myNS = (function () {
     function testAlert() {
          alert('test alert');
     }
     return {testAlert:testAlert};
}());

Now you can use myNS.testalert() in your inline javascript.

KooiInc
  • 119,216
  • 31
  • 141
  • 177
0

JS is made in such a way that you really can't totally avoid globals. (Well, you can, sort of. If you never give anything a name. But that tends to cause more problems than it solves.) When you call testAlert from some other script, you're operating under the assumption that testAlert is global. If it weren't, you couldn't just call it from anywhere like that.

You can minimize the chance of collision, though, by adding your stuff to an object that serves as a namespace, like so:

// don't clear it out if it already exists.
// that way all of your scripts can use your namespace, if you want.
// what you're really trying to protect against, are strangers picking names
// like yours. 
if (!window.myNamespace) myNamespace = {};

// example function
myNamespace.testAlert = function() { alert("test alert"); };


myNamespace.testAlert();

This way, the only name that has a good chance of conflicting is myNamespace.

I was going to show an example of a namespaced global...but ya know what? A namespaced global is still a global. Global variables are something you want to try and get rid of in most cases.

cHao
  • 84,970
  • 20
  • 145
  • 172
0

You need some sort of global variable so that you can access the method you're looking for. The fact that you have <script>testAlert()</script> means you expect testAlert() to be defined in the global namespace.

What I like to do (especially when using YUI, which you have tagged this question with), is to create a global object that acts as a utility class.

var page = {
    init: function() {
        // Do some initialization...
    },
    testAlert: function() {
        alert("Test Alert");
    }
};

After you do that, you can use the single global "page" variable to access everything you need.

// e.g.
page.testAlert();

// or...
Y.on("domready", page.init, page);

Again, for the second example I'm assuming you're using YUI, since you tagged this question with it.

Brendan
  • 1,853
  • 11
  • 18