Click here to Skip to main content
15,891,607 members
Articles / Programming Languages / Javascript
Article

JavaScript and Scoping

Rate me:
Please Sign up or sign in to vote.
2.55/5 (8 votes)
18 Jan 2015CPOL4 min read 14.2K   6   17
JavaScript and scoping

Introduction

Well, it's been a while since I posted and it boils down to the holidays. There's nothing like the holidays to throw your whole life out of whack. If you are like me, then you keep your life as organized as possible and it's the only reason you are able to function. And that got me thinking about this blog post and gave me an idea.

I've been preparing some articles on MVC, and even a presentation. Something I likely will be taking to code camps, and presenting to even my students at HACC. And that got me thinking about how one of the greatest strengths of MVC is the flexibility and ability to organize code into self contained modules. By building this out, we can organize our code into separate pieces of classes and navigation controllers. We can isolate code and maintain loose coupling to make for more testable code.

Now I can't tell you how many times I've seen wonderful code fall apart. Too many times, I've seen people say "we're using MVC" and say that like it guarantees that your code is not only using current technologies but is correct and architected properly. MVC is a framework, just like any other, and that means that just like any framework, it is only as good as the design of the code and the work of the programmers. If there was a technology that guaranteed good code, we'd all be out of a job.

Now that being said, there are lots of developers out there who leverage MVC correctly. They use the proper separation of concerns. They set up their controllers, using a logical grouping of the controllers and controller actions. But that is a whole other post on to itself, and the ways MVC can be abused.

But all that aside, the one place I see the most abuse of basic structure and patterns is JavaScript. For example, let's say you write code like the following in partial view:

HTML
<div>
Number 1 : <input type="text" id="Number1" /><br />
Number 2 : <input type="text" id="Number2" /><br />
<input type="button" id="btnAddNumbers" onclick="AddNumbers()" value="Add Numbers" />
</div>

Now like any good developer, you put your JavaScript code in a separate JS file called "Add.js". And it contains the following code:

JavaScript
function AddNumbers() {
var num1 = parseInt($("#Number1").val());
var num2 = parseInt($("#Number2").val());
var total = num1 + num2;
        alert(total);
    }

Now to most of us, this looks like perfectly fine JavaScript code. Nothing really special here. When you go to add this to a page, you add a reference to the JS file in the head tag of your page. And all is well, right?

Not quite... see right now, the JavaScript code above is being declared in what is called the Global namespace. Meaning that the code is being declared at the page level, and everything in this function is available to the entire page.

The question is, what happens when another developer writes a partial view with the following HTML:

HTML
<div>
Number to increment:<input type="text" id="NumberValue" /><br />
<input type="button" id="btnAdd" 
value="Increment Number" onclick="AddNumbers()" />
</div>

And they write the following function:

JavaScript
function AddNumbers()
{
     var num = parseInt($("#NumberValue").val());
     num = num + 1;
     $("#NumberValue").val(num);
}

And they declare their JS at the bottom of the page, thinking that it would load at the end, and insert their partial view into the same view as yours. The question is what is going to happen now? There are two functions declared with the same name. If this were server side code, we would get a compilation error.

But seeing that this is JavaScript, if I entered a "1" in the "Number 1" textbox, and a "2" in the "Number 2" textbox, and clicked the "Add Numbers" button, I would get a "NaN" in the "NumberValue" textbox.

Now why is that? Because when the browser loads the page, it does so from the top down, which means that it replaces the "AddNumbers" function with the one that does the incrementing. This is because JavaScript handles functions in much the same way as objects. So by declaring it in the global namespace, you are allowing for the potential that your code could be replaced by someone else's.

So what can you do? To be honest, the best option is to scope your JavaScript so that it doesn't sit in the global namespace, and presents this type of situation. You do that by treating a function just like an object, and modify your code in the following manner.

JavaScript
function CalcMath() {
var addNumbers = function () 
        {
var num1 = parseInt($("#Number1").val());
var num2 = parseInt($("#Number2").val());
var total = num1 + num2;
            alert(total);
        }
return {
            AddNumbers : addNumbers
        }
    }

This creates an object called "CalcMath", and a "method" off of that object called "AddNumbers". And this allows me to update the button to have the following:

HTML
<div>
Number 1 : <input type="text" id="Number1" /><br />
Number 2 : <input type="text" id="Number2" /><br />
<input type="button" id="btnAddNumbers" onclick="CalcMath().AddNumbers()" value="Add Numbers" />
</div>

Now, if someone adds a function called "AddNumbers", it has no affect on your partial view. This allows for everything to say modular, and separated and keeps other code from impacting your code in the future.

Many of the JavaScript frameworks out there (Angular, Knockout, etc.) are based on this principle, and use it as a foundation for the other benefits they provide.

So that's it for right now, more to come about the presentation, and more specifically more to come on resources for startups, and articles on lessons learned from my own current startup work.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
My name is Kevin Mack, I'm a software developer in the Harrisburg Area. I have been a software developer since 2005, and in that time have worked on a large variety of projects. Everything from small applications, to mobile and Enterprise solutions. I love technology and enjoy my work and am always looking to learn something new. In my spare time I love spending time with my family, and learning new ways to leverage technology to make people's lives better. If you ask me what I do, I'll probably tell you I can paid to solve problems all-day-every-day.

Check out my blog at https://kmack.azurewebsites.net/ and https://totalalm.azurewebsites.net/

Comments and Discussions

 
GeneralMy vote of 2 Pin
Florian Rappl5-Apr-15 6:55
professionalFlorian Rappl5-Apr-15 6:55 
GeneralRe: My vote of 2 Pin
Kevin Mack5-Apr-15 17:12
Kevin Mack5-Apr-15 17:12 
GeneralRe: My vote of 2 Pin
Florian Rappl5-Apr-15 23:49
professionalFlorian Rappl5-Apr-15 23:49 
GeneralRe: My vote of 2 Pin
Kevin Mack6-Apr-15 8:29
Kevin Mack6-Apr-15 8:29 
GeneralRe: My vote of 2 Pin
Florian Rappl6-Apr-15 10:52
professionalFlorian Rappl6-Apr-15 10:52 
GeneralRe: My vote of 2 Pin
Kevin Mack6-Apr-15 15:42
Kevin Mack6-Apr-15 15:42 
GeneralRe: My vote of 2 Pin
Florian Rappl6-Apr-15 21:46
professionalFlorian Rappl6-Apr-15 21:46 
GeneralRe: My vote of 2 Pin
Kevin Mack7-Apr-15 4:24
Kevin Mack7-Apr-15 4:24 
For the record I was showcasing how wrapping it in the revealing module pattern created a method of utilizing and ensuring that the "AddNumbers" that was being called was the intended version as per the developer so I did respond and solve the problem defined above.

Also for the record you have been insulting from the beginning. This is not a mediocre article as defined by the other reviews I've gotten. You just disagree with the approach used and that is fine. But you are not the one true expert on javascript and have chosen to put down others work rather than engage in a discussion.

For example, rather than say "Interesting choice, I would have gone differently what about this." You have chosen to state that it is your mission to prevent articles like this one from spreading bad practices. This is not a bad practice and for those who are newer to javascript have found approaches such as this quite helpful. Especially for smaller scale situations. I recognize that there are other more complex patterns that can be used and never claimed their weren't.

But as to your further above statements...Just because you believe a pattern to be "Standard" doesn't mean it is. Javascript is known for its flexibility and the pattern documented above has been utilized in MANY articles on this site as well as others. So you saying that this approach is "not standard" is opinion not fact.

Second you call out Node.js and the acceptible patterns utilized there. Point of fact, nothing is this entire article makes any reference to node.js. So any points on that fact are invalid.

I do not advocate the use of inline javascript, it is a fact. And even if you aren't using inline this problem still exists if external js files are being used. So I am pointing back to the problem and it is not misleading. If two developers build two js files both with an "AddNumbers" function and they are imported into the page then it would have the exact same result. I kept everything in line to clearly and simply illustrate the point. I am showing a means where you can attach scope to your underlying javascript and make sure that the partial view being used is associated with a wrapper function to ensure that if someone else creates a function with the same name, all logic on the original view is associated with the scoped version.

The use of inline was simply to keep things clean and simple when illustrating the point. I am not writing articles promoting and encouraging the use of bad practices. To say so in itself is insulting.

So based on my perspectives your statements above are not fact, just an opinion, and you are more than welcome to your opinion but attacking the intent and content of an article with that opinion is not what you have accomplished here. I did not mean to insult you, but was defending myself. I do encourage on many of the articles I've submitted any feedback and a constructive dialogue. I absolutely agree with you if new green field development there are many stronger patterns that can be used but for those with lower skill levels, approaches like this can server as a stepping stone as they work towards those approaches. I do agree with you that this approach is 100% not appropriate for use of Node.js, and agree with you with regard to the many other patterns, and some that are stronger.

But its also worth mentioning that many of those patterns, depending on requirements could be over-engineering a problem. I was just showcasing if you are writing simple javascript to solve an issue and need to do it client side, utilizing a pattern like this can minimize risk and make for a stronger solution.

If you are insulted, that is not my intent, but you have not been to the fact and have been pretty insulting yourself throughout this dialogue. I welcome a discussion that does not come from a place of attacking the solution and the intent but instead a place of spreading awareness. But as you pointed out above it was your "Mission" to eradicate articles like this.

GeneralRe: My vote of 2 Pin
Florian Rappl7-Apr-15 5:27
professionalFlorian Rappl7-Apr-15 5:27 
GeneralRe: My vote of 2 Pin
Kevin Mack7-Apr-15 6:06
Kevin Mack7-Apr-15 6:06 
QuestionGreat job, just one question... Pin
Member 1124134021-Jan-15 5:12
Member 1124134021-Jan-15 5:12 
AnswerRe: Great job, just one question... Pin
Kevin Mack21-Jan-15 14:07
Kevin Mack21-Jan-15 14:07 
GeneralRe: Great job, just one question... Pin
Member 1124134027-Jan-15 10:03
Member 1124134027-Jan-15 10:03 
QuestionNice Example Pin
Suchi Banerjee, Pune20-Jan-15 1:55
Suchi Banerjee, Pune20-Jan-15 1:55 
AnswerRe: Nice Example Pin
Kevin Mack20-Jan-15 2:14
Kevin Mack20-Jan-15 2:14 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun18-Jan-15 18:47
Humayun Kabir Mamun18-Jan-15 18:47 
GeneralRe: My vote of 5 Pin
Kevin Mack19-Jan-15 0:52
Kevin Mack19-Jan-15 0:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.