JSLint doesn't like var - javascript

I was probing my code for errors with JSLint and so far I managed to fix all bugs except the problem when my global application variable is undefined.
I was using this code before JSlint which worked properly:
var APP = APP || (function {
return {
init: function () {
}
};
}(window.document));
then I would call
APP.init();
to initialize. But JSlint doesn't like global variables so I changed my code to this:
(function (global){
var APP = {
init: function () {
}
};
return APP;
}(window.document));
This code passes the JSLint test with no problem, but then
when I call APP.init(); it says that APP is used before it was defined, which is true.
What would you recommend so that I don't use global variables but still create my application object, while my code passes JSlint test?

First code
In your original code, the actual error you would have gotten was
#1 'APP' used out of scope.
var APP = APP || (function() { // Line 1, Pos 11
It is not because JSLint hates global variables, but because it doesn't like the variable being assigned to it is defined in the same var statement.
Changing your code to use a different variable name would fix this problem
var app = APP || (function() {...}(..));
but then, one would expect that APP is already defined in the current scope. Otherwise you will get
#1 'APP' was used before it was defined.
Second code
It doesn't work because, APP is visible only inside the function object you created. It is not visible anywhere outside it. Since you want to define APP in the global scope, you just have to attach it to the window object, like this
(function(global) {
global.APP = {
init: function() {
}
};
}(window));
Then
APP.init()
will work fine.
Instead of going through all these, you can straight away define APP like this
window.APP = {
init: function () {
"use strict";
...
}
};

(function (global){
var APP = {
init: function () {
}
};
return APP;
}(window.document));
the above creates a scope/closure, so that only code inside your anonymous function can access the APP variable. JSHint has settings so you can set acceptable globals (such as jquery etc), I'd add APP to that and if the rest pass you know you only have that one variable/module as global. If you are using any 3rd party libs chances are you already have several global vars anyway

Before you give up on JSLint, know that it doesn't mind globals at all; it just wants you to declare them with a special format so that others reading your code know exactly what's going on.
The only "trick" here is if there's a chance your global APP isn't initialized yet and you really need to check for its "truthiness", as you do with APP = APP || (function.... Then you do need to use the window (or whatever your global object is -- it's different if you use Node, for example) prefix trick.
Here's how:
/*jslint white:true, sloppy:true, browser:true */
/*global APP */
window.APP = window.APP || (function () {
return {
init: function () {
window.alert('JSLint doesn\'t like empty blocks');
}
};
}(window.document));
APP.init();
And JSLint is happy!
I'm not against JSHint in theory, but that same flexibility that allows you to set all sorts of extra settings also tends to erode conformity, which is largely what I find the best benefit of a code linter to be. Give both a good, solid run, and see which you like best!

Related

Why wrap your angular controller code with anonymous function?

I've been seeing a number of people wrapping their controllers with:
function(){
//CODE
}();
What's the benefit / goal there?
That isn't really anything related directly to Angular, it is a JS pattern know as an Immediately Invoked Function Expression.
It is one of the most useful patterns in JavaScript, primarily because of:
Code Encapsulation
Since functions have closures in JS, we can use this pattern to create private data very easily:
var index = (function iife() {
var counter = 0; // <-- this is private, only available inside the closure of inner()
return function inner() {
return counter++;
};
})();
console.log(index()); // 0
console.log(index()); // 1
console.log(index()); // 2
console.log(index.counter) // undefined
We can also pass arguments into an IIFE, which allows us to control how we access the outside context of our IIFE. For example, to make sure $ is actually the jQuery object within your code:
(function ($) {
// here have access to the global jQuery as $ regardless of what window.$ is and
// how many libraries are trying to use $
})(jQuery);
By combining the two ideas above, IIFEs can also be used to implement the module pattern, which is the basis for how RequireJS and NodeJS separate code:
var myModule = (function iife(initData) {
// we can use initData here to initialize our module if necessary
var module = {};
// private vars ...
var privateVar1, privateVar2;
// private methods ...
function privateMethod() {
console.log('yeeey');
}
module.somePublicProperty = 1;
module.somePublicMethod = function() {
privateMethod();
};
return module;
})(/* pass initialization data */);
myModule.somePublicMethod(); // 'yeeey'
The reason you'll find a lot of JavaScript code wrapped in an anonymous function is to isolate it from other code on the page.
The following code will declare a variable called name on a global scope:
var name = "Hello World";
By using that code, any other script on the page attempting to use a variable called name could potentially get an unexpected value of "Hello World" because your script declared it as "Hello World".
By wrapping that code in an anonymous function, you keep the code from conflicting with other variables called name:
(function() {
var name = "Hello World";
})();
In the example above, name is now only available inside of the scope of the anonymous function. It is not global, and therefore cannot conflict with other code on the page.
By wrapping your Angular module in an anonymous function, you prevent your code from conflicting with other code.
Additionally, other people who may use your code won't have to worry about it changing their global scope.
IMHO it's not necessary, even superfluous, as most controllers are already functions:
'use strict';
angular.module('MyApp').controller('AboutController', ['$scope'
function ($scope) {
$scope.title = 'About Us';
}
]);
Everything #nem035 and #tcasey said is correct but it also have another side effect.
If you use tools like Grunt or Gulp it also allow you to have working dists to put in production.
If you do not use Immediate Invoke Pattern you'll most likely have minification problems like:
State X is already defined!
Unknown provider
. . .
I suggest you to wrap all your js modules with this pattern.
I hope I've been helpful.
There are many benefits of you immediately-invoked-function-expression short IIFE and it's best practice to use it. This way each of angular service or controller become isolate and you don't run into global variables as it can happened if you don't use IIFE.
read more about it

Javascript Module Usage

I'm just getting started with javascript modules and I want to make sure I'm doing it correctly.
Below is an example of the methodology I'm following, based on the "Loose Augmentation Pattern" that I read about here
//myApp.js
var myApp = {};
//someModule1.js
(function (ma) {
ma.someModule1.DoStuff = function () {
alert("hi");
};
return ma;
}(myApp || {}));
//someModule2.js
(function (ma) {
ma.someModule2.DoMoreStuff = function () {
alert("ho");
};
return ma;
}(myApp || {}));
//someModule3.js
myApp.someModule1.DoStuff();
myApp.someModule2.DoMoreStuff();
The myApp variable within myApp.js would be the only variable that's globally exposed, with all of the other modules and their functions only being accessible via this variable.
someModule3.js isn't necessarily a module, but any arbitrary javascript wanting to access the properties of the myApp object (After the appropriate modules have been defined).
The part in particular I'm not 100% clear on is this: (myApp || {}, jQuery)
What is that part called and what exactly is it doing (I know the whole thing is a closure, but I just don't understand exactly how the last part is working)?
It seems like "ma" is initially nothing, I add a function to it in the body of the closure, then return ma. At this point myApp only has the one function.
In the bit at the end (myApp || {}), is it actually saying "ma isn't nothing, it's actually called myApp and I'll append those functions to that object if it exists."
Is that right or am I way off?
I see four issues:
Your code won't run as is. You have to define .someModule1 before you can assign to it.
There's no reason to do return ma because you aren't using the return value.
There's no reason to pass myApp || {} because if myApp is not defined, then your code will do nothing because the object you created would not be capture in any variable and will just be immediately garbage collected and not be accessible.
As you've shown your code, the IIFE you've enclosed the code in is not accomplishing anything other than adding lines of code and complexity.
Here's more detail on each issue.
Your modules won't run as is. You need to define .someModule1 by changing this and there is no reason in your code to pass myApp || {}:
//someModule1.js
(function (ma) {
ma.someModule1.DoStuff = function () {
alert("hi");
};
return ma;
}(myApp || {}));
to this:
//someModule1.js
(function (ma) {
// you must define .someModule1 before you can assign properties to it
ma.someModule1 = {};
ma.someModule1.DoStuff = function () {
alert("hi");
};
return ma;
}(myApp));
There is also no reason to do return ma in your code since you are not using the return value.
The reason myApp || {} is of no value here is because if myApp is not defined, then none of the code in your module does anything useful because the underlying object you would be assigning things to is not captured in a variable anywhere. So, if myApp is not defined, then your code accomplishes nothing. So, somewhat by definitino, myApp has to already be defined for your code to be useful, therefore, you can just pass myApp into the IIFE.
As you've shown the code, there is no benefit or reason to putting the assignment of properties inside the IIFE. You don't have any closure variables or anything that is private inside the IIFE. So, you would achieve exactly the same result with this:
myApp.someModule1 = {};
myApp.someModule1.DoStuff = function () {
alert("hi");
};
There are some reasons for using an IIFE, but you don't show any in this code example. Personally I'm a fan of using the simplest code that achieves your objectives and not adding extra complexity just for sake of it. Other people like to put all their code inside these IIFE modules. I only put my code inside an IIFE when there is actually a reason to have your code in an IIFE.

use `module` as namespace

I've been using a pattern in my node.js modules that seems so obvious to me that I assume there must be something wrong with it or I would see more people doing it. To keep private variables that are global to the module, I simply attach them as properties on the module object. Like so:
module.exports = {
init: function() {
module.someClient = initializeSomethingHere()
},
someMethod: function(done) {
module.someClient.doSomething(done)
}
}
This seems preferable to me than something like this...
var someClient;
module.exports = {
init: function() {
someClient = initializeSomethingHere()
},
someMethod: function(done) {
someClient.doSomething(done)
}
}
...because in the second example you need to go searching for var someClient at the top of the file to make sure that the omission of the var keyword is intentional within the init method. I've never seen this pattern used elsewhere though, so I wonder if I'm missing something that makes it less than ideal.
Thoughts?
There are a couple of possible downsides that come to mind.
1) It's technically possible for those properties to be accessed and modified outside the module, but only if a reference to the module itself is available outside it. Something that makes the module available through its own exports (module.exports = module; being the simplest example) would expose them.
2) You could have a naming conflict with a builtin property or a future builtin property that doesn't exist yet (which would cause your code to break in future versions of node.js). This could be very problematic and very hard to debug. Currently the built-in properties on a module object are: children, exports, filename, id, loaded, paths, and parent.
because in the second example you need to go searching for var someClient at the top of the file to make sure that the omission of the var keyword is intentional within the init method.
If that is the reason, you could just use a namespace that isn't module. For instance by adding var private = {}; to the top of each file and then using private.someClient instead of module.someClient.
Also 'use strict'; so that the accidental omission of var is an error and not an accidental global.
Drawbacks
Option 1: This practice is prone to naming conflict with a builtin property or a future builtin property that doesn't exist yet, as #paulpro stated in his answer.
Option 2: If you miss var keyword and expose the someClient globally. Besides you need to go searching for var someClient at the top of the file all the time.
Alternative
As JavaScript has function scope it's better to define everything within a function. Creating private and public members within a function. Below is a design pattern which one can follow:
'use strict';
module.exports = (function(){
//private
var someClient;
//public properties
var that={};
that.init = function() {
someClient = initializeSomethingHere()
},
that.someMethod: function(done) {
someClient.doSomething(done)
}
//expose only the required methods
return that;
})();
Here only exposed methods are those which are attached to that object. And all rest are private to the function scope. Even if you miss the var keyword in someClient it won't be accessible out side of the function, which won't ever happen if you use 'use strict' at the top.
Logic is first time when you require the xyz.js file it will return the that object rather than the function.

Inject node module variable to scope

Is it possible to do achieve this behavior using node modules?
module.js:
module.exports = function () {
var test.fn = function () {
console.log("$test.fn()");
}
var test.fn2 = function () {
console.log("$test.fn2()");
}
var variable = "test";
};
app.js:
require("./module.js")();
test.fn();
test.fn2();
otherFunction(variable);
I dont want to do anything like this $ = require("./module.js")(); $.test.fn();
I want to inject this variables into app.js scope without wrapper variable.
Edit:
I have ended up using this:
module.js:
module.exports = function () {
eval(String(inject));
var inject = (
this.$module1 = {},
this.$module1.fn = function () {
console.log("$module1.fn()");
}
);
};
app.js:
require("./module.js")();
$module1.fn();
The top level scope in a module is actually a function scope (the node.js loader wraps each module in a function that it then calls to execute the code in the module). Thus, there is no publicly available "root" object that we can programmatically assign properties to.
So, that means that it is not possible in a module to programmatically add new variables at the top level of the module scope without using eval() in a fairly big hack. Function scopes just don't work that way in Javascript.
You could also have the module assign things to the global object where they can be used without a prefix, but this is NOT a recommended practice in any way. The whole point of node.js modules is to avoid using any globals and to make code entirely self contained with little chance of global collisions.
Or, you could have your module export a giant string of Javascript and then eval() it inside of app.js in order to define new variables in the module scope. Again - not recommended.
Your best best is do things the "node.js way" and put everything on an object and export that object. Here's one variation:
app.js
var test = require("./module.js")();
test.fn(); // "executing fn"
test.fn2(); // "executing fn2"
console.log(test.myVar); // "test"
module.js
module.exports = function () {
return {
fn: function () {
console.log("executing fn");
},
fn2: function() {
console.loog("executing fn2");
},
myVar: "test"
}
};
You can do something like that using an IIFE. The method, when required, will automatically run and return an object, which you can then use in your application.
module.js:
global.test = (function() {
return {
fn: function() {
console.log("executing fn");
},
fn2: function() {
console.log("executing fn2");
},
variable: "test"
}
})();
app.js
require("./module.js"); //just include, no need for a wrapper variable
test.fn();
test.fn2();
console.log(test.variable);
Note that this technique will overwrite the global variable test if it already exists.
This answer should not encourage you to use global within your node.js modules (see jfriend00's comments above) as it makes your code vulnerable for name collisions with other modules and thus your modules less portable.
Within module.js you have access to the global object of node.js runtime environment.
module.js:
global.test = {
fn: function() {
//Do something
},
fn2: function() {
//Do something different
},
variable: "test variable"
}
app.js
require("./module.js"); //just include, no need for a wrapper variable
test.fn();
test.fn2();
console.log(test.variable);
Note that this technique will overwrite the global variable test if it already exists.

javascript immediately invoked function

Hi friends I got doubt after seeing below code. I know below code is creating an object and assigning to app variable. but what is the use of use all parameter. Can anybody will help me to understand, what it does and what is the benefit. please share if there is any useful link.
var app = (function (app, $) {
}(window.app = window.app || {}, jQuery)));
It takes window.app and jQuery from your global scope and injects them into your function. It's a neater way of doing this:
var app = function(app, $)
{
}
app(window.app = window.app || {},jQuery);
The benefits of this is that you are creating your own scope. Any javascript you put into this function will not be in the global scope. This can prevent variables being overridden etc.

Categories