I'm using JSLint to verify most of my external Javascript files, but the largest amount of errors I'm getting is from functions being used before they're defined.
Is this really an issue I should worry about?
It seems Firefox, IE7 and Chrome don't care. Functions like the popular init() (which I use often) normally stick at the top as that makes sense to me (I like to pretend it's analogous to main()) will, according to JSLint, need to be pushed to the bottom of the file.
As this is the top rated google hit and other people might not be seeing it at first in the jslint tool, there is a option called "Tolerate misordered definitions" that allows you to hide this type of error.
/*jslint latedef:false*/
If you declare functions using the function keyword, you can use them before they're declared. However, if you declare a function via another method (such as using a function expression or the Function constructor), you have to declare the function before you use it. See this page on the Mozilla Developer Network for more information.
Assuming you declare all your functions with the function keyword, I think it becomes a programming-style question. Personally, I prefer to structure my functions in a way that seems logical and makes the code as readable as possible. For example, like you, I'd put an init function at the top, because it's where everything starts from.
If you're using jshint you can set latedef to nofunc, which will ignore late function definitions only.
Documentation - http://www.jshint.com/docs/options/#latedef
Example usage:
/* jshint latedef:nofunc */
noop();
function noop() {}
Hope this helps.
From jslint's website (http://www.jslint.com/lint.html), you can read about a /*global*/ directive that allows you to set variables that are assumed to be declared elsewhere.
Here is an example (put this at the top of the file):
/*global var1,var2,var3,var4,var5*/
The :true :false is not actually needed from my experience, but it looks like it's recommended from what I read on the site.
Make sure the initial global statement is on the same line as /*, or else it breaks.
To disable this warning in jshint for all files, place this in your .jshintrc file:
{
"latedef": false
}
In your .jshintrc file, set:
"latedef": "nofunc",
it is very unfortunate the latedef option was removed. This is essential when trying to create a 'class' with an interface at the top, ie,
function SomeClass() {
var self = this;
self.func = func;
function func {
...
}
}
This style is very common but does not pass jsLint because func is 'used' before being defined. Having to use global for each 'member' function is a total pain.
You can always declare the offending function at the top
eg:
var init;
.... but then you'll have to remove the "var" when you get to the true definition further down:
init = function() {
};
Related
Working in ReactJS, I run into an issue where imported functions that are 'unused' are failing to be recognized by the program and I believe are not being added to the window.
In my case, I'm trying to be able to import functions from other files and then call them by string name.
Ex)
import {myFunction} from '../otherFile';
functionNameString = 'myFunction'
window[functionNameString]() //call function by it's string name
//ERROR: window[functionNameString] is not a function
Without changing my above syntax, I've found two ways I can resolve this:
Add the actual function to the same file as the window[functionNameString]() call
Explicitly assign the function to the window at the top of my file like window.myFunction = myFunction
I'm trying to avoid the first case to keep this file shorter, but also don't understand why I need to do the explicit assignment of the function to the window as shown in the second case (and why defining the function in the same file doesn't need this)
Overall, my question is how can I avoid this explicit assignment of and have these imported functions callable from import (or in a shorter syntax)? Assigning like so is fine for a function or two, but I'm looking at importing 15 funcs from this other file which makes things messy working in this fashion. Thanks!
Modules have their own scope, they aren't at global scope, and imports are created as bindings within the module scope, not globals. That's at least half the point of modules: to not make everything global anymore.
Overall, my question is how can I avoid this explicit assignment of and have these imported functions callable?
They are callable. myFunction() will call your function in your example code. There's no reason whatsoever for window to be involved.
If you need to refer to them by a name in a string for some reason, you can put them in an object:
const functions = {
myFunction,
// ...
};
Then functions[functionNameString]() will work.
I was experimenting to define the built-in method alert() to see what kind of error the console will throw, but instead the built-in alert() got overridden.
This is the code -
function alert(some_string) {
console.log(some_string+some_string);
}
function say() {
alert("Hello");
}
say();
The output is : HelloHello
Coming from a Java background, it would throw a compile error as :
error: method alert() is already defined
So what happened here? Did I actually override the method?
Overriding is a classical OO term which means that a child class has method with the same name as one of the classes it inherits from which is used instead of that method on the child class.
In this case, you are straight up taking the alert variable (which by default has a value of a function provided by the browser) and assigning it a new value (the function you just declared).
(That assumes you are working in the global scope. If you were in a local scope you would just be masking the variable so you would only be making alert inaccessible to other code in the same scope … and since you were writing that code too, it wouldn't be a problem because you would know if you needed the global alert and could avoid reusing its name.)
There might be hundreds of built-in functions and I might accidentally define a function with a same name as one of them, how can I check if such accidents don't happen?
There are two basic techniques for this.
Avoid creating globals
When you create a new variable, do it in as narrow a scope as possible. A common pattern is to use an IIFE to create a new scope for all the variables related to a given piece of code.
(function () {
"use strict";
function alert() {
// Locally scoped alert that doesn't get in the way
// of any variable called `alert` from the browser
// or another library
}
})();
Use namespaces
This is just a term for having a single global as the entry point to a bunch of related code. It is usually given an ALL_CAPS name that is unlikely to conflict with other code.
This allows the functions to be accessed from anywhere, like globals, without creating lots of global variables.
var MYLIBRARY;
(function () {
"use strict";
MYLIBRARY = {
alert: alert
};
function alert() { /* etc */ }
})();
File 1
var M = function (speech) {
"use strict";
document.getElementById("speech").innerHTML = speech.toString();
};
File 2
$("#test").click(function () {
M("hello");
});
JS lint probelms v
http://puu.sh/j8AOo/a24a88825b.png
'M' was used before it was defined.
This error is because you're defining M as a global variable in one file, and attempting to invoke it in another. Because global variables are often a sign of code-smell, JSLint makes you specifically declare them. There are a few options to do this. For one, you could prepend File 2 with /*global M*/, and it should stop complaining.
Missing 'new'.
This is based on variable conventions. In JavaScript, we typically only name constructor functions using CamelCase. Because constructor functions are intended to be called with the new keyword, it's detecting this as an error. In this case, your best option is probably to just rename M to m.
For more information on configuration and other JSLint help topics, see this page. Alternatively, if you have any say at all in the matter, I would strongly suggest checking out JSHint instead.
What are the benefits of using self executing functions with a framework, such as, Angular?
I am new to Angular but my understanding thus far is the module-based design gives most of the benefits that the Self executing function gives. What am I missing? Is it just a matter of style?
Here is an example by Ben Nadel. I really like the style but want to understand if there are any gains by writing Angular code this way or if it is mostly a style choice.
Mainly, it ensures that your code is not declared on the global scope, and any variables you declare remained scoped within your function.
In this case, it also has the benefit of declaring the objects required to run the code in one place. You can clearly see at the bottom that the angular and Demo objects are passed in, and nothing else. If the code was not wrapped in the function, you'd have to scan through the code to see what the dependencies were.
Personally, I prefer to use a module loader like RequireJS, which effectively forces you to follow this pattern.
That's kind of a opinion question. The main advantage I see on self executing functions is to not create global variables. I had never seen this pattern with angular.
On the example link you gave, it does not seem to have any advantage. The angular variable will exist anyway on a angular application, so you could use angular directly. And the Demo being a module, you can add controllers to it without without messing with the global scope.
I like a lot of self executing functions. But in this case I really don't see an advantage.
Daniel, you said: "if it is mostly a style choice".
I know at least two examples in javascript when "code style" is not only matter of preference but it causes different result.
Are semicolons optional? Not at all.
$scope.test = function() {
console.log('Weird behaviour!')
} //; let us comment it
(function() {} ()); //two functions seem to be independent
is equal to
$scope.test = function() {
console.log('Weird behaviour!')
}(function() {} ()); //but without semicolon they become the one
Another example of "code style" which is not related to self-executing functions:
var x = (function() {
return //returns undefined
{};
}());
alert(x);
/*
that is why, I suppose, while writing javascript code,
we put function brackets in the following "code style":
function() { //at the same line
return { //at the same line, this style will not lose the object
};
}
*/
Code style formation is dictated by unexpected results of such kind.
Last but not least.
With selfexecuting function: a closure is created on function call and keeps your vars local.
A closure is created on function call. That is why self-executing function is so convenient. As Daniel correctly mentioned it is a good place for keeping an independent code unit, this pattern is called module pattern. So when you move from pure javascript to specific framework or vise versa this independence enables code changes to be more fluid. The best case is just moving your module to an angular wrapper and reusing it.
So it is convenient for the purpose of code transmission from one technology to another. But, as I believe, it does not really make sence for specific framework.
I've seen the next way of writing self-invoking functions:
(function (app) {
app.foo = {
bar: function(){}
};
}(App));
Where App is a global object.
I wonder, why do we need to pass App as a param into a function? Why don't just use this:
(function () {
App.foo = {
bar: function(){}
};
}());
I see only one advantage of using the first way. If we for some reason rename the App object, then we can easily rename the param in brackets and our code will work as it works. But in case of the second way we will probably need to rename App in all places where we use it.
Are there other differences?
It means that the contents of the function – with regards to the app identifier – are agnostic to the global (or parent) scope.
One of the scenarios in which this is done is, for example, with jQuery, when you don't want to assume that the jQuery object is called $ (e.g. if no-conflict mode is on), but you do want to call it by that name. Passing it through an anonymous function like this (i.e. (function($) {})(jQuery)) allows you to generate a locally-scoped alias that doesn't interfere with the external meaning of the name $ in the parent/global scope.
The other answers explain the benefit of having a locally scoped copy. There are a few other benefits too:
As a micro-optimization it reduces scope lookups (it's less expensive to find a local var than a global one).
It can help in the minification process as all your params are reduce to single letter named vars.
It gives you a pseudo dependency management technique...in your example, you know your code is dependent on App.
For example, many libraries use the "$" character as a shortcut for their main function (e.g. JQuery). This is convenient, but can cause a clash when using multiple libraries. So, you could pass JQuery in like this:
(function($) {
// Code
var nav = $('#nav');
// More code
})(JQuery);
That way, you can still use the convenient shortcut, but you can also avoid clashes (as long as you also configure the libraries not to use the "$" shortcut).
You can also use it to redefine global variables locally to ensure they contain whay you expect:
(function($, undefined) { ... })(jQuery);
Where undefined is now the expected undefined. Also see: What is the purpose of passing-in undefined?
Most other uses are well covered in the other answers.