I have some functions inside of functions and I am having trouble retrieving a variable. It will be easier to show in code I want to log the var three in the testit function but not sure how to do so.
test();
function test(){
var abc;
function one(){
abc = 1;
two();
}
var three;
function two(){
console.log(abc);
three = 2;
testit();
}
one();
}
function testit(){
console.log(three);
two();
}
to make test an object you would do the following:
function test(){
this.abc = 0;
this.three = 0;
this.one();
}
test.prototype.one = function(){
this.abc = 1;
this.two();
}
test.prototype.two = function(){
console.log(this.abc);
this.three = 2;
}
test.prototype.testit = function(){
console.log(this.three);
this.two();
}
and run it like so:
testObj = new test();
testObj.testit();
hope this helps.
edit: BTW: if you put a call in function 'two' back to function 'testit' you'll end up with an infinite loop.
Here's an explanation of what's happening:
When you wrap code in a function, you get what's called function scope. This means that the scope within the function belongs to the function and not to a scope above or outside of it (whichever way you want to look at it).
A closure allows an expression (typically, a function, as MDN states) to have it's own scope while sharing the scope of it's outer or higher scope.
So, let's look at an example:
// This represents the global, or window, scope.
// Analogous to window.outer_var.
var outer_var = 'outer var';
function outer_func() {
// New scope! Local only to outer_func and those
// expressions (functions) *enclosed* by
// `outer_func(){...}, e.g. inner_func(){...}.
var inner_var = 'inner var';
// Only outer_func() or inner-enclosed (to
// inner_func()'s definition) functions can
// access inner_func().
function inner_func() {
// Another new scope! Can access inner_var
// and inner_func_var (below). outer_func()
// canNOT access inner_func_var, though.
var inner_func_var = 'inner func var';
}
}
outer_func(); // Of course, it's in scope and accessible.
inner_func(); // This will cause ReferenceError: inner_func is not defined error.
Simply as it is (no wrapping context, with a closure), var outer_var is created with the global or window scope. It may be accessed in all of the following:
console(window.outer_var);
function outer_func() {console.log(outer_var);}
function inner_func() {console.log(outer_var);} No matter where inner_func's defined.
Here, #2/3 are analogous to:
function outer_func() {console.log(window.outer_var);}
function inner_func() {console.log(window.outer_var);}
Or global this:
function outer_func() {console.log(this.outer_var);}
function inner_func() {console.log(this.outer_var);}
Now, inner_var is accessible from the following:
function outer_func() {console.log(inner_var);}
function inner_func() {console.log(outer_var);} Only from within outer_func().
inner_func() may also only be accessed within outer_func(), because it belongs to the outer_func() scope, and thus is not visible/accessible outside of outer_func()*.
Lastly, inner_func_var is only accessible by:
function inner_func() {console.log(inner_func_var);} Only within outer_func().
To access your three variable, you have three choices:
Make three globally accessible (globals are generally discouraged as they may easily introduce difficult to resolve bugs when one is overwritten by some other code).
Return three from your test() function. In this case the value is accessed, not the actual variable within the function.
Create a property as #logic8 demonstrates, so it may be accessed as a property of an object.
* This isn't entirely true. outer_func() could export a reference to the function out of scope with return inner_func;. This is a more advanced concept, though, and won't be addressed here in depth. Here is an example.
You have to put it in a global to do so:
test();
var three = false;
function test(){
[..]
}
function testit(){
console.log(three);
two();
}
when you declare a variable with var it becomes local to that scope. If you want to access three in both functions, you can either declare it without var (making it global - generally frowned upon for good reasons) or declare it outside of the two functions: var three;
The correct way to do this is by using the closure pattern in javascript. This wraps your javascript class in its own function so anything you declare within that file is only local to your code.
Using jQuery, this is easily accomplished like so:
(function($){
//your code goes here
})(jQuery);
People typically do it this way so their javascript only executes when the page is ready:
$(document).ready(function(){
//your code goes here
});
It's a bit more complicated without jQuery if you want to execute your code when the document is ready:
document.addEventListener('DOMContentLoaded', function(){
console.log('document is ready. I can sleep now');
});
With your code, it would look something like this:
$(document).ready(function(){
var test = function(){
//test code here
};
var one = function(){
//one code here
};
var two = function(){
//two code here
};
var three = function(){
//three code here
};
var testIt = function(){
//test code here
};
});
This way, you can safely access all of your functions from the others without polluting the global namespace.
Related
I know there are a lot of posts here and elsewhere about selfexecuting functions but I still have some questions after reading posts.
why would I ever assign a self-executing function to a variable? If seems that they execute themselves anyways.
var myFunc=(function() {
console.log('Hello World');
})();
I read a lot that the reason to use self-executing functions is to keep variables private. If I have a not self-executing function, everything I define inside that function is gonna be private anyways?!
(function() {
var name="my Name"
console.log(name);
})();
vs.
function() {
var name="my Name"
console.log(name);
};
//its the same
So I dont quite understand how self-executing functions are to keep local scope (as you can do that using not self-executing functions) so the only reason I see is to use them when you want to execute automatically for example on page load.
Thanks!
just one more question:
var test=(function myFunc(){
var name="Hello World"
return {
test1: function(){
return name;
},
test2:function(){
return name+"1"
}
}
})()
test.test1()
vs
var test=function myFunc(){
var name="Hello World"
return {
test1: function(){
return name;
},
test2:function(){
return name+"1"
}
}
}
test.test1()
--> what exactly happens here that because of IIFE I can actually execute test.test1() and not with a regular function?
You usually wrap your functions in a anonymous function when you want to keep your scope contained. This is also part of the module pattern which is still pretty popular:
https://toddmotto.com/mastering-the-module-pattern/
Then you can assign the outcome of that IIFE to a variable so your scope can only be accessed by calling that variable.
myScope.myLocallyScopedProperty or myScope[myLocallyScopedProperty]
Your other function needs to be called manually and it also accessible from anywhere.
I suggest reading the article by Todd Moto it explains a lot.
If that IIFE doesn't return anything, then there's indeed absolutely no use to assign it to anything. Though there may of course be examples of IIFEs returning something you want to use later; in that case the IIFE is a private scope to set up some object for example:
var foo = (function () {
var bar = 'something';
// here be dragons
return baz;
})();
This gives you a private scope to assemble baz without unnecessarily leaking temporary variables into the global scope.
There's no difference in those examples, except that the second one doesn't execute and therefore never does anything. Scoping and the purpose for the scoping are unchanged.
First, briefly, these are not self-executing functions. (That would be a recursive function.) These are inline-invoked function expressions (IIFEs). The function doesn't call itself, the expression calls the function.
why would I ever assign a self-executing function to a variable?
That's not what that code does. It assigns the result of calling the IIFE to the variable. You'd use it when you want that result, for instance:
var x = (function() {
var n = 0;
return {
increment: function() { return ++n; }
};
})();
console.log(typeof x); // "object"
console.log(x.increment()); // 1
console.log(x.increment()); // 2
x doesn't receive the IIFE, it receives what that IIFE returns — in this case, an object with a function on it.
I read a lot that the reason to use self-executing functions is to keep variables private. If I have a not self-executing function, everything I define inside that function is gonna be private anyways?!
Yes, that's true. You use an IIFE when you only need to do what's inside the IIFE once. Otherwise, absolutely, you define the function, give it a name, and then reuse it wherever you need it. The variables inside the function are indeed private to it (unless exposed in some way), and are specific to each call to the function.
1: To assign an IIFE to a local Variable makes sense for something like that:
var getID = (function () {
var id = 0;
return function () { return id++; };
})();
This way you can get new IDs without running the risk to reset the internal counter from anywhere else in the code, except by redeclaring the variable.
2: Basically you create Scope by creating a function. But if you do not execute it, well, it doesn't do anything. So if you have that:
function () { return 'foo' };
How do you want to call it if it is not assigned to a variable or does not have a name? By itself it wont do anything, since it is not called. Something like that is dead code and can safely be removed.
your first thing has no sense whatsoever:
var myFunc = =(function() {
console.log('Hello World');
})();
myFunc is not a function and it is undefined.
The sense, as I see it, for a self executing function is to package some code that has to be executed right away.
var p1=1, p2=2, obj = {
prop: (function(x,y){ return x+y;})(p1, p2)
}
OR
avoiding overwriting already defined functions/objects in the case your script will be inserted in a already existing application and also creating a kind of private methods, if you like:
function aFunction() {
console.log('a code');
}
(function(w) {
function aFunction() {
console.log('b code');
}
w.run = function() {
aFunction();
};
})(window)
aFunction();
run();
You use self executing functions to expose only what you need out of a scope. I think I have a somewhat clear example:
let myObject = (function(){
let privateVariable = "I'm private";
function privateMethod() {
//private method
};
function methodToExpose() {
//this method I will expose
}
//what is returned here, is what is public
return {
PublicMethod: methodToExpose
//other public properties
}
}());
So, the function gets executed immediately, and what happens is I have an object that is defined by what I returned from the function.
Another example I could give you is to retain variables of the current scope inside a closure, but you wouldn't really use it that much, since we now have let. A practical example:
<span id="1">old</span>
<span id="2">old</span>
<span id="3">old</span>
<span id="4">old</span>
<script>
var toPrint = "";
for (var i = 1; i <= 4; i++) {
toPrint = "new: " + i;
document.getElementById(i.toString()).addEventListener('click', function(event){ event.target.innerHTML = toPrint; })
}
</script>
When you click on a span, the value will be replaced with the value... "new: 4"!
That's because when you finished executing, that's the value that toPrint has. The function assigned to the click event retrieves that toPrint, and at the time it retrieves it, it is "new: 4". We solve this with closures:
<span id="1">old</span>
<span id="2">old</span>
<span id="3">old</span>
<span id="4">old</span>
<script>
var toPrint = "";
for (var i = 1; i <= 4; i++) {
toPrint = "new: " + i;
document.getElementById(i.toString()).addEventListener('click', function(event){
var currPrint = toPrint;
return function(event){ event.target.innerHTML = currPrint ; };
}())
}
</script>
By using a self executing function, we save the current value of toPrint in the currPrint variable inside a local scope. When we later click on a span, the function assigned to the click even will use the variable currPrint, which contains the value that toPrint had at the time the function was assigned, not the value that toPrint has at finished execution.
Note that this is solved also by using let instead of var, but still, it's an example of self-executing functions :)
In the form of IIFE (or immediately invoked function expressions), they can then be used to create plugins or used as namespaces and attached to window / jquery / or other global level object for use later.
When you name a function like assigning anonymous function to a variable, you can use it later by calling the variable with parentheses, in your example, defined myFunc with
var myFunc=(function() {
console.log('Hello World');
});
Use it later in code as myFunc();
In your example, you are storing the output of function directly in variable, by calling it immediately, and there is no output to be stored.
So, if you later write console.log(myFunc);, there is undefined as output.
Better IIFE example from your code samples is the one mentioned below.
(function() {
var name="my Name"
console.log(name);
})();
It executes, does a console.log and that's it. Adds nothing to namespace or the global object in your case.
The last of your examples defines a function, does not execute it then, and since it does not have a named variable assigned, or a name, it gives syntax error and cannot be used later in code. So, below example is useless.
function() {
var name="my Name"
console.log(name);
};
You have added two more examples with var test = function myFunc. First one will work fine with test.test1(). For the second one, you need to evaluate test as a function first and then call its function, like test().test1().
I guess you miss something here. Just to make basic things clear - if you assign a self executed function to a variable the actual return value of the function when executed at this time is assigned to the variable and not the function itself.
var myFunc = (function() {
console.log('Hello World');
})();
myFunc(); // will throw error: TypeError: myFunc is not a function
myFunc === undefined
var myFunc = (function() {
console.log('Hello World');
return 'japp';
})();
myFunc(); // will throw error: TypeError: myFunc is not a function
myFunc === 'japp'
So why is this pattern around?
IIFEs are very useful to
limit the scope
if you declare
var test = 'test'; // var test actually will be assigned as a property of the current context (this)
window.test = 'test'; // so you pollute the global namespace which is not a good practice
so this would be mouch better
(function() {
var test = 'test';
})();
another very good thigs with IIFs is that you can achieve a design with "privates"
var myFunc;
(function() {
var i = 0; // i is available for myFunc with private access
myFunc = function() { console.log( ++i ) };
})();
myFunc(); // logs 1
myFunc(); // logs 2
Hello Stackoverflow people,
The questions, is about code style and code maintainability, rather than search for some errors.
Let's assume that I am creating some module for node.js. This module, is exporting only one object, let's call this object "FileParser". During file parsing, there can be different preprocessing functions. They are very unique, and I am not planning to reuse them in other parts of the application.
Since, this module is exporting only one function - my question is next:
In case I have some utility functions for this module, should I define this functions in the function which is exported, or they should be defined outside this function.
Basically- this:
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
var utilityFunction = function(){
//do some work, maybe even return values
}
//do some other work.
utilityFunction();
//do more other work
}
module.exports.FileParser = FileParser;
or this:
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
//do some work before calling function
utilityFunction();
//do more and more work after calling function
}
function utilityFunction(){
//body of function goes here, maybe even returning some value
}
module.exports.FileParser = FileParser;
What is more readable, especially if there are few utility functions.
Thanks,
-D
If utilityFunction is not used as a closure (i.e. it does not access variables declared in the methodToExport function), there is no good reason to declare it inside that other function.
Put it outside, it makes the methodToExport shorter (and therefore more readable).
Since it resides in your "local" module scope, you don't even need to bother about global namespace pollution. If the number of utility functions grows, you might consider grouping them appropriately, e.g. by using the revealing module pattern.
In the first case, your function will be declared each time methodToExport is called, in the second you will have global function. Maybe you can use some kind of closure:
FileParser.prototype.methodToExport = function() {
function utilityFunction () {
//do some work, maybe even return values
}
return function () { // This is the real function, the one which will be export!
//do some other work
utilityFunction () ;
//do more other work
} ;
} () ;
Maybe there is a better way, but I would have done things like that!
JavaScript is flexible enough to permit such thing, the declaration bellow, works but is not a good pratice in my point of view.
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
var utilityFunction = function(){
//do some work
}
utilityFunction();
}
module.exports.FileParser = FileParser;
You're declaring and call inside a function, but is more clearly to do this inside the declaration of your FileParser object.
So, you have good pattern of declaration the Revealing Pattern, proposed by Addy Osmani.
var FileParser = function(){
var utilityOne = function(){
}
this.methodToExport = function(){
// do some work
utilityOne();
}
}
module.exports.FileParser = FileParser;
This able you to hide some utility function as a kind of encapsulation, and show only the important functions outside.
You didn't ask about this, but I would recommend that you place your code inside an IIFE so there's one less variable in the top level closure, like this:
module.exports.FileParser = (function(){
var FileParser = function(){};
// Do your stuff
return FileParser;
})();
This saves your having to create a global variable for FileParser.
Now as for the question which you did ask -- should the utility function be defined within the exported function or outside of it -- my answer depends on whether you're only exporting a single function, or multiple. In your case, since you're only exporting a single function, my answer is that as long as you have a choice, I prefer the utility function defined outside because its closure scope is smaller that way. By "as long as you have a choice", I mean that your utility function isn't using anything defined within methodToExport.
module.exports.FileParser = (function(){
var FileParser = function(){};
var utilityOne = function(){};
FileParser.prototype.methodToExport = function(){
// do some work
utilityOne();
}
return FileParser;
})();
A smaller closure scope doesn't make much of a difference in most circumstances, but the following is an example where it does.
module.exports.FileParser = (function(){
var FileParser = function(){};
FileParser.prototype.methodToExport = function(){
var longArray = [ /* ... */ ];
var utilityOne = function(){
setInterval(function(){
console.log("Hello");
},1000);
};
utilityOne();
}
return FileParser;
})();
In the above example, longArray is in the closure of utilityOne() even though it isn't needed. The setTimeout's reference to longArray prevents it from being garbage collected.
module.exports.FileParser = (function(){
var FileParser = function(){};
var utilityOne = function(){
setInterval(function(){
console.log("Hello");
},1000);
};
FileParser.prototype.methodToExport = function(){
var longArray = [ /* ... */ ];
utilityOne();
}
return FileParser;
})();
Moving the utilityOne() definition out of the method definition shrinks its closure scope and allows the longArray to be garbage collected.
So this is the first time I am using Javascript in a much more powerful context, having a thick client and doing much of the heavy-lifting through javascript in itself. I am using jQuery, and a lot of the code is getting muddy at the moment coz it's all just a bunch of functions.
Turns out for some of my functions, I required variables to be passed through multiple functions with their value being maintained. The obvious way of doing this is by declaring them outside of the scope of the function and then have the function manipulate it the way it ought to . (These variables are objects and not primitive type, so I guess javascript being pass by reference, this works).
For instance, I probably have something like this
var node = //init with some value;
$(document).ready(setup);
function setup()
{
A();
B();
}
function A()
{
// operate on var node
}
function B()
{
// operate on var node
}
This is obviously a scaled down version of my code, but captures the way I deal with global variables. My question is, is there a more elegant way to do the above ?
Thanks
Any reason why you can't do:
$(document).ready(function() {
var node = //init with some value;
setup(node);
function setup(node) {
A(node);
B(node);
}
function A(node) {
// operate on var node
}
function B(node) {
// operate on var node
}
});
In general, using global variables and functions is a bad idea and should be avoided wherever possible.
Note that while you appear to have been asking specifically about node, your functions setup, A and B are also all global variables in your version.
The simplest approach would be to put all these declarations inside an anonymous function:
$(document).ready(function() {
var node = ...;
function A() {
...
}
function B() {
...
}
function setup() {
A();
B();
}
setup();
});
Only use one global variable (or as few as possible). Make any functions or objects members of your one global variable.
Douglas Crockford says
An objective measure of the quality of a JavaScript program is How
many global variables and global functions does it have? A large
number is bad because the chance of bad interactions with other
programs goes up. Ideally, an application, library, component, or
widget defines only a single global variable. That variable should be
an object which contains and is the root namespace for all of your
stuff.
Yahoo’s single global is YAHOO. It is spelled in all caps to identify
it as something special, since all lower case is ordinary and initial
caps indicates a constructor. Being in all caps, it is unlikely that
someone would use it accidentally, which further reduces the
likelihood of collision.
http://www.yuiblog.com/blog/2006/06/01/global-domination/
Also, you can create objects to further organize your code.
GLOBAL.myObject = {};
GLOBAL.myObject.myFunction = ...
I prefer the "revealing module" pattern:
var myApp = (function () {
// privates
var node;
var a = function () {
// operate on node
};
var b = function () {
// operate on node
};
// publics
var init = function () {
// initialization stuff
a();
b();
};
return {
init: init
};
})();
$(document).ready(function () {
myApp.init();
});
This way you only ever have one global, myApp, which stores everything else your app needs.
I think it makes the code harder to understand, I'd much rather take the variable in as an argument and have it as a return.
$(function(){
var outcome = multiply(add(5));
});
function add(num)
{
return num+1;
}
function multiply(num)
{
return num*5;
}
If you feel like you absolutely want to have global variables wrap your stuff in a closure so it doesn't actually go to a global scope.
ie,
(function(){
var a; // can be used in any functions within this closure, but not polluting window
function A()
{
a = 'blah';
}
})();
There are many. For instance, objects.
// jQuery shorthand for "wait till DOM ready"
$( function() {
// create node object
var node = {
id: /* some value */,
setup: function() {
this.A();
this.B();
},
A: function() {
// operate on this.id
},
B: function() {
// operate on this.id
}
};
// setup node object
node.setup();
} );
Global variables are trouble waiting to happen. Don't dirty up your global namespace. Javascript is an object oriented language, use objects. Notice your object can have a property that you can reference with the this keyword from within the objects methods.
A couple of days ago I have learned on my own example how bad global variables and functions are. So apparently the best solution is NOT to use them, however sooner or later I will need to reuse my variables and functions over and over again.
So my question is: Can I reuse my functions and variables without declaring them globally? Can it be done?
For example, I want to reuse my alertBox function and my containsP variable couple of times:
DEMO: http://jsfiddle.net/ajmyZ/
//I am BAD GLOBAL FUNCTION inside var
//But I am reusable!!!
var alertBox = function () {
alert("Hey I am BAD function!!")
}
$(document).ready(function () {
//I am BAD GLOBAL var
//But I am reusable TOO!!!
var containsP = $("div p:first");
containsP.click(function () {
alert("Hi BAD var HERE!!");
});
$("p").eq(1).click(function () {
alertBox();
});
//I am the NICEST function here
//but I am NOT reusable :(
$("p").eq(2).click(function () {
alert("I am the NICEST function here!!");
});
});
I guess the simplest way to avoid clobbering the global object is just to create your own "application context". You can do that, by creating a self-invoking function which wraps your whole js-code within each file.
(function( win ) {
"use strict";
var still_global_but_only_in_this_anonymous_closure = true;
$(document).ready(function() {
// ...
// accessing the global object:
win.some_global_property = true;
});
}( this ));
Actually, you're already creating such a local context with your anonymous function you pass into .ready(). This is just the more explicit way. That self-invoking method, just calls itself with the global object as argument (where you still can explicitly access global variables). Furthermore, by invoking "use strict"; you're protected from accidently creating global variables alá "Ops_I_Forgot_The_Var_Statment = true;
The code you posted has no global variables. A variable declared inside of a function (in the case of your example, the anonymous document.ready handler) will never be global unless you make one of two mistakes:
forget the var keyword, making an implicit global
explicitly say window.myVar = ...;
I have couple of Js functions say fn1(), fn2().
fn1() would be called automatically when the page loads
<script >
window.onload=fn1();
function fn1()
{
var list_temp=new Array();
list_temp.push("testing");
//etc
}
function fn2()
{
// Do something after getting the data from fn1()
}
</script>`
Now I need to access the list defined in fn1() from fn2(). Is there anyway that could be done? I remember reading somewhere that functions in Javascript are in a way equivalent to objects?
You could define a variable in the global scope, but you can also wrap your two functions in a closure and make the variable private (local) to that closure:
(function() {
var list_temp = [];
window.onload = fn1;
function fn1()
{
list_temp.push("testing");
// etc...
}
function fn2()
{
console && console.log(list_temp);
// Do something after getting the data from fn1()...
}
})();
simply declare
var list_temp=new Array();
before
function fn1 ()
on the same level of
window.onload
vars declared at top level script are globals ...
In JS var scope is the function ...
window.onload=fn1();
That doesn't run fn1 when the page loads. That runs fn1 immediately and assigns its return value to window.onload. Exactly like x = foo();.
Now I need to access the list defined in fn1() from fn2(). Is there anyway that could be done?
No, not as defined. list_temp is a local within fn1. Unless you put it somewhere that fn2 can access it (some shared scope), fn2 can't access it.
Here's an example of shared scope (and fixing the window.onload thing):
(function() {
var list_temp=new Array(); // Or better, var list_temp = [];
window.onload=fn1; // No () at end
function fn1()
{
list_temp.push("testing");
//etc
}
function fn2()
{
// Do something after getting the data from fn1()
}
})();
Or, of course, you could make list_temp global. But that's not generally a good idea.
You can chain the functions together:
function fn1()
{
var list_temp=new Array();
list_temp.push("testing");
//etc
fn2(list_temp);
}
function fn2(data)
{
// Do something after getting the data from fn1()
}
I remember reading somewhere that functions in javascript are in a way equivalent to objects?
Yes, all functions are objects, inheriting from a common Function prototoype. And you can set your own properties on them as on all objects, but that won't help us here.
Now I need to access the list defined in fn1() from fn2()
You can't. The variable declaration of list_temp is scoped to the function, it is not available from outside. So you could either
move the variable declaration in a scope where it is visible to fn2
export the list object to some other variable that is visible to fn2. The easiest way would be using the return statement, for example.