Javascript, using one single local object instead of many local variables - javascript

I often use jslint and tools to verify my code for programming errors, etc...
During the course of my programming I often find that I need a local variable or a local function to do some simple things. So I go to my main single var statement at the top of my local scope and adjust it, sometimes breaking my creative flow. So sometimes instead I declare a single line var in the middle of my code to continue my programming and then move it at the top var statement during refactoring afterwards.
I had an idea today that i want to explore and did not find anything on it on Google or stackoverflow.
My idea is this, just declare a single temp object and use it for whatever the need. Ex: adding some attribute for a new variable or function.
So instead of :
// if I omit the last comma, the next variable will be a global
var variable1 = "Hello World!",
variable2 = "Testing...";
(... some code ...)
var variable3 = 42;
I would instead use :
var temp = {};
temp.variable1 = "Hello World!";
temp.variable2 = "Testing...";
(... some code ...)
temp.variable3 = 42;
So I do not risk polluting the global namespace, I declare variable as needed and do not struggle with that var statement since I always know that a variable preceded by "temp." is in the local scope.
Any comment or advice will be appreciated.

Ask yourself a question: have you ever seen anyone else doing this? I, personally, haven't. That should give you an indication that there are good reasons not to.
Essentially what you're suggesting is "namespacing", isn't new. It is fine in many cases but here - for temporary variables - I'd suggest it highlights a code smell.
You mention pollution of the global namespace but this should rarely be an issue. By breaking your code down into functions, classes or modules, your variables will be enclosed in that scope.
So sometimes instead I declare a single line var in the middle of my
code to continue my programming and then move it at the top var
statement during refactoring afterwards.
This sounds bad. It sounds like your code blocks are very long, and that is an indication that you should be extracting functions from your code.
I'd also point out that you're also polluting the global namespace with a variable called temp in your example.
Think about common JavaScript codebases; jQuery only has the jQuery or $ variable exposed. Lodash/Underscore only has _. Backbone has "Backbone" and so on. Why is your application special? Just have one exposure point.
Another potential solution to your issue is to use a module system. When compiled, the code will be wrapped in a closure and not exposed to the outside world at all. Making it modular will also result in a tidier application.

The best way to avoid global scope pollution is to break your code down in small and independent functions and modules.
Your mention having to refactor your code because you have variable declarations in the middle of your code. I personally don't think you need to do that, I actually find code way easier to reason about when variables are declared as close to the place they are used as possible. As long as you are comfortable with the way the scope and hoisting works I don't see a reason why you should put all your declarations at the top of your functions.

Related

Javascript local variables - is it worth using them?

It gets said a lot that local variables are faster than globals in JavaScript Eg:
function ()
{
// Local variable
var a = 9
}
For instance, I've been thinking of aliasing the global Math object to a local Mathl variable or alternatively aliasing specific (much used) functions to a local variable/function like Mathround() instead of using Math.round().
Now the things that I'm thinking of doing this with (eg Math.round() ) can be used plenty of times per animation frame (50ish) and there could be 60 frames per second. So quite a few lookups would be avoided if I do this. - and that's just one example of something I could do it with. There'd be lots of similar variables I could alias.
So my question is - is this really worth it? Is the difference tangible when there's so many lookups being avoided?
If you don't know whether it's worth it, then it's probably not. In other words, you should address performance issues when they happen by identifying, measuring, and testing situation-specific alternatives.
It's hard enough to write clear, readable, maintainable code when you set out to write something humans can understand. It's a lot harder if you set out trying to write something that computers can execute faster (before you even know what faster means in terms of your application). Focus on clarity and address performance problems as they arise.
As for your specific example. If you're dying to know the answer, then test it.
Lookups will be faster if you scope parent-scope variables locally. How much faster? Is the difference noticable? Only you can tell by measuring the performance of your code.
It isin't that rare to see the document being aliased to a local variable.
Have a look at this part of the ExtJS library for instance.
(function() {
var DOC = document,
However like already stated, beware blindly aliasing object member functions because you might run into this value issues.
E.g.
var log = console.log;
log('test'); //TypeError: Illegal invocation
//you could use bind however
log = console.log.bind(console);
Say you have this code:
for(...) {
someFunc();
var y = Math.cos(x);
...
}
To execute the Math.cos(x) the JS VM must a) compute location of global Math object and b) get cos property of it. Just in case someone inside that someFunc() doesn't do crazy things as this for example:
Math = {};
In general in JS access to local variable is similar (if not exact) to access to array element by known index. Access to global objects is pretty much always look-up by key in maps.

What is the consequence by not using var in a require declaration in node.js? [duplicate]

This question already has answers here:
What is the purpose of the var keyword and when should I use it (or omit it)?
(19 answers)
Closed 8 years ago.
When I want to import a 'class' in node.js I do this at the beginning of the file:
var MyClass = require('./MyClass.js');
what if I do this:
MyClass = require('./MyClass.js');
without var?
Is there a downside by not using var and placing this variable in global context?
if you declare a variable in a global scope, putting var or not has no difference
if you declare a variable with a var in a function then you create a local variable inside that function
if you create a variable without a var inside a function, it will look up the scope chain until it finds the variable or hits the global scope
Is there a downside by not using var and placing this variable in
global context?
the biggest downside is you will clutter the global namespace that makes the code hard to maintain. there are a lot of things you must consider on declaring global variables especially in javascript you can have a further reading on this article http://c2.com/cgi/wiki?GlobalVariablesAreBad
another thing is you can stil refer to javascript resources when your concern is about node.js because node.js's primary language is javascript
To answer your question "is there a downside?", yes, there are downsides and there are upsides to using global scope... despite the ubiquitous warnings about global scope, you can use it effectively under some circumstances in some languages in some contexts if you plan accordingly, have enough information about your application and the various components that make it up, etc etc etc...
In my experience, node doesn't provide any compelling reasons to use global scope, so you're opening yourself up to the dangers without experiencing any of the potential benefits. You have to be mindful about passing your variables around, but that's the "node way", it's designed specifically to work that way and javascript in particular is very good about allowing you to do that in ridiculously powerful ways.
The short answer is that, if this is a module for inclusion in other projects, then you're courting disaster by introducing your variable into the global scope of projects where you couldn't hope to understand how that could effect things. If this is a standalone application, so long as it remains trivial and will not grow and evolve over time, you're probably OK using the global scope as a shortcut. The more your application grows and changes, the more likely you are to run into problems by not properly limiting scope.
Putting var in front of the variable definition defiles the variables in the local scope of the function you are in.
With no var the variable automatically goes into the global scope.
For more help see here.

What are some of the problems of "Implied Global variables"?

JavaScript: The Good Parts defines these kinds of declarations as bad:
foo = value;
The book says "JavaScript’s policy of making forgotten variables global creates
bugs that can be very difficult to find."
What are some of the problems of these implied global variables other than the usual dangers of typical global variables?
As discussed in the comments on this answer, setting certain values can have unexpected consequences.
In Javascript, this is more likely because setting a global variable actually means setting a property of the window object. For instance:
function foo (input) {
top = 45;
return top * input;
}
foo(5);
This returns NaN because you can't set window.top and multiplying a window object doesn't work. Changing it to var top = 45 works.
Other values that you can't change include document. Furthermore, there are other global variables that, when set, do exciting things. For instance, setting window.status updates the browser's status bar value and window.location goes to a new location.
Finally, if you update some values, you may lose some functionality. If, for instance, you set window.frames to a string, for instance, you can't use window.frames[0] to access a frame.
Global variable make it very difficult to isolate your code, and to reuse it in new contexts.
Point #1:
If you have a Javascript object that relies on a global var. you will not be able to create several instances of this object within your app because each instance will change the value of the global thereby overwriting data the was previously written by the another instance.
(Unless of course this variable holds a value that is common to all instances - but more often than not you'll discover that such an assumption is wrong).
Point #2:
Globals make it hard to take existing pieces of code and reuse them in new apps. Suppose you have a set of functions defined in one file and you want to use them in some other file (in another app). So you extract them to a new file and have that file included in the new app. If these function rely on a global your 2nd app will fail at runtime because the global variable is not there. The dependency on globals is not visible in the code so forgetting these variables (when moving functions to new files) is a likely danger.
They're global variables, so yes, all of the "usual dangers" apply. The main thing that distinguishes them from global variables in other languages is that:
You don't explicitly declare them in a global scope. If you mistakenly omit var in a variable declaration, you've accidentally declared a global variable. JavaScript makes it a little too easy to unintentionally declare global variables; contrast this with Scheme, which raises an error if a variable is not defined in the global scope.
Global variables, at least in the browser, are aliased by window[variable_name]. This is potentially worrisome. For example, some of your code might access window['foo'] (with the intention of accessing a global variable). Then, if you accidentally type foo instead of var foo elsewhere in the program, you have declared a reference to window['foo'], which you meant to keep separate.
One issue is that you may be trampling on already defined variables and not know it, causing weird side effects in other parts of the code that can be a bear to track down.
Another is that it is just sloppy code. You should not be creating variable with more scope than they need since at the very least it keeps more variables in memory and at worst it can create data scenarios you didn't intend.
The bottom line is that when you do that you don't know for sure that you are not messing up other functions that use a global variable of the same name. Sometimes it isn't even your fault, a lazy programmer of another plugin left something global that was meant to have scope inside of a function. So it is a very practical safeguard for writing better and less buggy code.
The problems of typical global variables is that they are, well, global - there is no scope to enclose them, and any code that you are executing / interacting with (such as a library that you call down the road) could modify the variable without a warning.
However, these problems are compounded in Javascript by two things:
You can define a global variable anywhere - the only requirement for that is to forget the var keyword.
It is extremely easy to define a global variable when you had no intent to do so. That is the problem that "implied" globals have over "typical" globals - you will create them without even knowing you did.
In a reasonably-designed language that includes truly global variables (ok, so not that reasonably-designed), you would have a limited handful of places to define globals, and it would require a special keyword to do so.

Naming/formatting standard for global variables

What is both the naming and formatting standard for global variables in JavaScript?
For example:
var global_var // ?
var _global_var // ?
var GLOBAL_VAR // ?
var _GLOBAL_VAR // ?
...
Note: I am NOT talking about constants, just simply variables that have global scope.
There are no standards as such. The most common practice is to use lower camel case (e.g. var fooBarBaz;) for all variables and property names, irrespective of scope, but this is by no means universal. The only exception is to capitalize the name of a function that is intended to be used as a constructor:
function SomeClass() {}
var someClassObj = new SomeClass();
I've also seen block capitals and underscores used for variables that the author considers constants, or alternatively for all global variables:
var EARTH_RADIUS = 6378100;
Another reasonably common convention (although not one I use myself) is to prefix properties of objects that author wishes to be considered private with an underscore:
this._leaveThisAlone = "Magical property";
Douglas Crockford published his own take on JavaScript code standards several years ago that covers most of this, but as ever this is just one man's opinion, so take with a pinch of salt.
The requisite comment about rethinking the design if you're needing to use global variables, blah blah...
The global variables I've seen are normally prefixed with g or gbl. Sometimes this is modified with an underscore: _g, _gbl. IIRC, the underscores were used when 'global' was confined to some scope and not 'truly' global.
If you are going to use a global variable in a fashion where EVERYTHING shouldn't be able to use the variable, I'd go with using the underscore. In javascript (IIRC) the convention of using an underscore as a prefix implies that the variable is 'private' or shouldn't be used externally. If you are, alternately, declaring it in a fashion that everyone should be able to access and modify then I'd go with just the prefix and no underscore.
One big reason people would tell you to not use global variables is to avoid interfering with other scripts and/or libraries.
A convention I started using when I need to use a global variable is to add my last name - this way I know I won't interfere with any libraries' or outside scripts' global variables. (Though I have a fairly unique last name - this might not work if you're a Smith).
So my global variables would be named:
var foo_lastnameGlobal;
var bar_lastnameGlobal;
I should point out (in case it isn't clear) this is just a personal convention, not a common or widely used one. It also helps me remember what my global variables are when I do use them. I suppose it might not be so great for public code or in a professional group work environment.
I think there are two intents of doing such a thing.
The first reason to do such a thing is to be able to discover your global state variables bound to global object(usually window or global) at a given time. The problem is that no matter how rigorous you are, there are only two practical ways of approaching this; first is to create a global variable to keep track of global variables by name and commit to always changing it whenever you add/remove a global, second is to keep a copy of initial state of global and figure out which properties were added, removed, or changed since start.
The second reason to do such a thing is to emphasize in the code that it intentionally interacting with the global state. In this case, there is no standard, little benefit to doing this over adding comments or explicitly specifying the global object rather than doing so implicitly.
There is a lot of punishment for having inconsistent notation across code if you decide to change the way you denote a constant between files or projects. There are plenty of notations to choose from, and all of them fail one way or another, either by obfuscating the variable name and it's natural alphabetic ordering, or adding additional referencing overhead.
Personally, if in doubt, I like to stick to the Linux Kernel coding style, I find it tackles many problems sufficiently.
C is a Spartan language, and so should your naming be. Unlike Modula-2
and Pascal programmers, C programmers do not use cute names like
ThisVariableIsATemporaryCounter. A C programmer would call that
variable tmp, which is much easier to write, and not the least more
difficult to understand.
HOWEVER, while mixed-case names are frowned upon, descriptive names
for global variables are a must. To call a global function foo is a
shooting offense.
GLOBAL variables (to be used only if you really need them) need to
have descriptive names, as do global functions. If you have a function
that counts the number of active users, you should call that
count_active_users() or similar, you should not call it cntusr().
Encoding the type of a function into the name (so-called Hungarian
notation) is brain damaged - the compiler knows the types anyway and
can check those, and it only confuses the programmer. No wonder
MicroSoft makes buggy programs.
LOCAL variable names should be short, and to the point. If you have
some random integer loop counter, it should probably be called i.
Calling it loop_counter is non-productive, if there is no chance of it
being mis-understood. Similarly, tmp can be just about any type of
variable that is used to hold a temporary value.
If you are afraid to mix up your local variable names, you have
another problem, which is called the function-growth-hormone-imbalance
syndrome. See chapter 6 (Functions).
Not a standard but some ideas: G_variable_name, g_variableName, gVARIABLE_NAME.
If you want employeeID to be a global variable then the The correct method is to declare as
window.employeeID = 5;
and then use window.employeeID in all the places you would access later.

Javascript Function Scope

This is perhaps a dumb question, but I am new to Javascript and desperate for help.
If the Javascript engine will look for global variables outside of a function, then what is the point of passing parameters to it? What do you gain?
I understand that global variables are generally frowned upon, but I still don't understand the purpose of passing variables. Does it have something to do with data encapsulation?
There's a few magic words that are used by programmers to describe different kinds of functions. Here's a few:
Re-entrant
ThreadSafe
Referentially Transparent
Idempotent
Pure
Side-Effects
You can look some of them up if you want a headache. The point is that Computer science and engineering progress has always been about reducing complexity. We have spent quite a lot of time thinking about the best way to write a function to achieve that goal. Hopefully, you can stuff tiny bits of your program into your head at a time, and understand those bits, without having to also understand the overall functioning of the entire program simultaneously, or the detailed implementation of the insides of all the other functions. A function that uses global variables can't do that very well because:
You can't guarantee that the global variables exist
You can't guarantee that the global variables are what you think they are
You can't guarantee that other parts of the program haven't modified those variables in a way you didn't expect.
You can't easily generalise to use the function multiple times on multiple sets of variables.
You can't easily verify that the function works as advertised without first setting up the function's external environment and its dependencies.
If the global variables have changed in a way you didn't expect, it's really hard to track down which part of the program is the culprit. It could be any of 500 different functions that write to that variable!
On the other hand, if you explicitly pass in all the data a function needs to operate, and explicitly return all the results:
If something goes wrong with any of those variables, it's easy to find the source of the problem
It's easier to add code to verify the "domain" of your inputs. Is it really a string? Is it over a certain length, is it under a certain length? Is it a positive number? is it whole, or fractional? All these assumptions that your code needs to operate correctly can be explicit at the start of the function, instead of just crossing your fingers and hoping nothing goes wrong.
It's easier to guess what a particular function will actually do, if its output depends only on its input.
a function's parameters are not dependant on the naming of any external variables.
And other advantages.
if you were only going to use global variables that the functions worked on then you'd always have to know the inner workings of the functions and what your global variable names had to be for them to work.
also, something like Math.abs(n) would be hard to call twice in one line if using global variables.
Functions are reusable components of your code, that executes a particular snippet on the provided variable exhibiting varying behavior.
Encapsulation comes from being Object Oriented. Functions are more for giving structure to your program.
Also, you shouldn't undermine the execution time of a method, if the variable it access exists in the context rather than being global.
If you don't need parameters to be passed to functions, then, you really don't need functions.
Functions are usually (and should be) used to provide code re-use -- use the same function on different variables. If a function accesses global variables, then every time I use it it will perform the same action. If I pass parameters, I can make it perform a different action (based on those different parameters) every time I use it.
One of the main benefits is that it keeps all the information the function needs, nearby. It becomes possible to look at just the function itself and understand what its input is, what it does, and what its output will be. If you are using global variables instead of passing arguments to the function, you’ll have to look all over your code to locate the data on which the function operates.
That’s just one benefit, of many, but an easy one to understand.
Global variables (in any language) can sometimes become stale. If there is a chance of this it is good to declare, initialise and use them locally. You have to be able to trust what you are using.
Similarly, if something/someone can update your global variables then you have to be able to trust the outcome of what will happen whenyou use them.
Global variables are not always needed by everything so why keep them hanging around?
That said, variables global to a namesapce can be useful especially if you are using something like jquery selectors and you want to cache for performance sake.
Is this really a javascript question? I haven't encountered a language that doesn't have some form of global variables yet.

Categories