Is using `var` to declare global scope as bad as using `global` - javascript

I've learned that using globals is a bad idea in Javascript because there's the risk of collisions with dependencies.
Can I use var at the global scope as an alternative to this? I want to avoid the pitfalls of globals, but doing this seems much easier than passing along all my custom objects as parameters to functions. I have objects which are partially defined in many different files.

Can I use var at the global scope as an alternative to this?
var in global scope creates a global variable. So it's exactly the same and not in any way better.
If you are working with Node, there isn't really a need for globals. Every module should require all of its dependencies.

Related

Constant Functions Over Global Variables?

Global variables are bad, hopefully we are pretty much all agreed on that. But are global functions that only ever return one thing less bad?
var foo = 42; // this is bad
function foo() { return 42; } // less bad?
I get the feeling I can't be the first one to think of doing this, but am having difficulties thinking of the drawbacks.
You still have a global variable (and it is a variable, not a constant), the only difference is that the value of that variable is a function.
There are no benefits, and you have the overhead of calling the function whenever you want to get the value.
If you want a constant, then use a constant.
const foo = 42;
This still has the drawbacks of being a global and you should still aim to define your variables and constants in as narrow a scope as you can.
The main disadvantage of having globals (functions or variables) is that their names can collapse with other libraries or frameworks that you use in your application.
Also they negatively affect code reusability and code distribution.
Due to these reasons you should avoid using globals. Instead you should encapsulate these globals in some namespace and you should try your best to make the namespace name unique enough so that it does not conflict with any library or framework.

What does Crockford mean: "Javascript depends on global variables for linkage"?

In Javascript: The Good Parts Crockford writes that "Javascript depends on the global variable for linkage." I understand that in javascript if you declare a variable outside a function it "is in the global namespace" -- meaning you can access it anywhere in the program. I sort of understand how linkage limits where in a C++ program you can access a variable (regardless of its scope). With that said, what does Crockford mean?
I think what he means is that global variables are how you communicate with libraries. For example jquery uses the global variable $, underscore uses _, etc. You link to the libs through a global name.
Continuing
All the top-level variables of all compilation units are tossed
together in a global namespace called the global object. This is a bad
thing because global variables are evil, and in JavaScript they are
fundamental. Fortunately, as we will see, JavaScript also gives us the
tools to mitigate this problem.
What Crockford is referring to, I think, is the absence of module or namespace-like mechanisms in JS to segregate and modularize chunks of functionality at a macro level, where those chunks are explicit about what they are exposing (export), or what they are using from other chunks (import). However, as he points out, JS does provide the ability, albeit imperfectly, to do this through existing language features, and the world has not come to an end. At the same time, this problem is now being addressed on a number of fronts, notably the ES6 module mechanism.

Referring to non-widget objects in Dojo without "polluting" global namespace

What's a clean best practice for keeping track of and referring to general JavaScript objects - most likely Dojo-declared - that may have been declared in one area (read module) of an application but that need to be used in another area? We're assuming AMD here.
As mentioned by the "Non-Widgets" section of Dojo's "Using Declarative Syntax" reference guide:
... regular objects don't have a registry like Dijit based widgets do, therefore in order to be able to reference them after you instantiate them, you have to create a reference to them in the global scope.
Global scope? Rrraaughh?! One of the biggest things about "Modern Dojo" is the frowning upon willy-nilly usage of the global namespace:
One of the core concepts of "modern" Dojo is that things in the global namespace are bad. There are numerous reasons for this, but in a complex web application, the global namespace can easily become polluted with all manner of code [...]. This means in "modern" Dojo, if you are about to access something in the global namespace STOP because you are doing something wrong.
Also, from that guide:
Again, repeat after me "the global namespace is bad, the global namespace is bad, I will not use the global namespace, I will not use the global namespace".
In light of that, have there been any other popular ideas expressed about maybe having a general-purpose object registry that exists in the application's context? Is it feasible or perhaps obvious to just Dojo-define a module whose sole purpose is to be a mixed bag of references to objects that get used throughout the application?

Nodejs global variables and modules

Are there any security issuses or something with using global variables and assignig modules to global variables in nodejs?
example:
client = new Client();
Without the var statement, so i can use it everywhere?
It's not that it's a security problem, it's considered bad practice though and it can lead to other problems such as trying to override a Node.js global variable.
Try not to pollute the global namespace and if you really really need global variables, just use one with sub-objects.
I don't think there are security issues per se, but you will be polluting the global namespace. As your project grows (especially with more than one programmer) the risk of conflicts gets bigger. And what if you later on add a third party library to your project that has a variable named 'client'?
I've been using Node for a couple of years and I had the same "problem" you have and is frustrating. Nevertheless I can give you the solution I reached and it works for me.
Node doesn't allows global variables in the way you ask since variables defined as global in a module are global only for that module. But exists a GLOBAL object that ban be used for what you need.
Global variables are a bad idea in general (always), but having a global cache of useful functions in it's own namespace is not a crime at all since it will not override anything and lets you use it along your code. So I'll tell you what I do to share functions and objects between modules and keep source organized (that's important for me at least!):
1st Create a resource file where you place all important functions and objects you want to share across your code. I call mine "R.js", R from Resources
2st Define the "R" object that will store all functions and objects and assign it to node's GLOBAL object:
var R = {};
GLOBAL.R = R; // Adds resource module to global
3rd For sake of simplicity and avoid extra requires all arround the code, I do all needed requires inside R.js. After that you only need to use them with R.require_variable.function_or_property
// All needed requires
R.fs = require('fs');
R.net = require('net');
R.http = require('http');
R.dbClient = require('mysql').Client;
...
4th Create the shared functions, variables and objects you like inside the R object
5th Where needed arround your code, require the R.js file and access to it's member by using the R object
R.<property_or_function>
2 warning notes.
Remember to always call shared functions or user shared objects placind "R." in front of it
Althought you can assign new functions, objects and properties to R object anywhere this can lead to the same inconsistencies you would have with global variables if you don't plan it in advance - i.e. you call a shared function before assigning it to R - so as a methodology, create everything in the R.js file instead of doing it all arround your code. This way all shared things will be in R.js and that is the only place to look for shared code.

Global variables for node.js standard modules?

I know that global variables are bad.
But if I am using node's module "util" in 40 files in my framework, isn't it better to just declare it as a global variable like:
util = require('util');
in the index.js file instead of writing that line in 40 files?
Cause I often use the same 5-10 modules in each file, that would save a lot of time instead of copy paste all the time.
Isn't DRY good in this case?
You could just have a common module.
common.js:
Common = {
util: require('util'),
fs: require('fs'),
path: require('path')
};
module.exports = Common;
app.js:
var Common = require('./common.js');
console.log(Common.util.inspect(Common));
Each module is supposed to be independent. The require doesn't cost anything anyways after the first one for each module.
What if you wanted to test one module alone? You'd be having a lot of issues because it wouldn't recognize some "global" requires that you have in your app.
Yes, globals are bad, even in this case. Globals almost always ruin: testability, encapsulation and ease of maintenance.
Updated answer Jan. 2012
The global object is now a global inside each module. So every time you assign to a global variable (no scope) inside a module, that becomes part of the global object of that module.
The global object is therefore still not global, and cannot be used as such.
Updated Dec. 2012
The global object now has the global scope within the application and can be used to store any data/functions that need to be accessed from all modules.
global.util = require('util');
There's a section about global objects in the node documentation.
However, globals should be used with care. By adding modules to the global space you reduce testability and encapsulation. But there are cases where using this method is acceptable. For example, I add functions and objects to the global namespace to use within my unit test scripts.
I'm confused by the answers in this thread.
I am able to do this...
File: test.js
global.mytest = {
x: 3,
y: function() { console.log('Works.'); }
};
File: test2.js
console.log('Does this work?');
mytest.y();
File: server.js
require('test.js');
require('test2.js');
And it seems to work as the question needed. The first require places the mytest object into the global scope, then the second require can access that object without any other qualifiers.
I was trying to figure this out (which brought me to this thread from a Google search) and I wanted to post what seems to work for me now. Maybe things have changed since the original answers.
I have successfully been using the process object for passing around my configuration object. While in theory suffering from the exact same issues as mentioned above (encapsulation, testability and so forth) it works fine when using only non-state modifying properties (a hash table with primitives, basically).
If you wrap your modules in blocks (e.g. anon functions) you can bind to a local name (via parameter or 'var') and then have any arbitrary long (perhaps "package" labeled) name you want (if you even need a global at this point).
For instance, my modules often look similar to:
;(function ($, $exp, other) {
$(...)
other.xyz()
$exp.MyExportedObject = ...;
})(jQuery, window, some_module.other_expression) // end module
I use jQuery with noConflict, this the former, and the latter show you can do this for any expression -- global, require, computed, in-line, whatever... this same "wrapping" approach can be used to eliminate all (or almost all) "special named" globals -- globals must exist at some level, however, removing potentially conflicts is a very big win.

Categories

Resources