I have a function like this:
function run(arg) {
if (!window.alreadyRun) init();
window.alreadyRun = true;
/* more code */
}
You get the idea, I'm trying to figure out if it's the first time a function is called.
Is there a better way to do this? Without using globals? Something like this:
function run(arg) {
var ranAlready;
if (!ranAlready) init();
ranAlready = true;
/* more code */
}
This will return a function, with a variable called runCount which will hold the number of times it was called.
var yourFunction = function() {
var runCount = 0;
return function() {
console.log(runCount);
runCount++;
}
}
var a = yourFunction();
a(); // runCount: 0
a(); // runCount: 1
a(); // runCount: 2
a(); // runCount: 3
See it on jsFiddle.
If you just want to run an init type function, you could place the code above returning the inner function. It will be called once before returning the inner function, and its scope will retain to its outer function.
The power of closures.
var f = (function(run) {
return function() {
if (!run) init(),run=true;
// do code
};
}(false));
You can even use if (!run) init() && run = true and get init to return false if you want it to be called again on the next function call.
We have a self executing function which creates a local run variable and set's it to false by passing it in as an argument. We then have a single line which checks if it's false if so it does init(), run=true which is running the init function and assigning it to true in a single expression.
Basically anywhere were your using global scope to make the variable static to the function you can instead use a closure as a scope level between local function scope & global scope.
If you need a variable that is static to a function & read only you can use the little known const keyword.
I think closures are completely overkill for this, and only complicates the code.
What you're describing is known as a static variable in Object Oriented languages, and it can be mimicked quite easily in JS by attaching properties directly to the function. This is possible because functions are first-class objects in JS:
function run(arg) {
if (!run.ranAlready) { // run.ranAlready is undefined at first, so falsy
run.ranAlready = true;
init();
}
/* more code */
}
This is far simpler than nested functions, and you can continue to use run() in exactly the same way.
Another advantage is that, for unit testing, you can still access the ranAlready property from outside the function to check that your code is working correctly:
assert(run.runAlready == false);
run();
assert(run.runAlready === true);
Granted, this can't be used for anonymous functions, such as in event handlers, but isn't it much cleaner to give that anonymous function a name instead of using nested functions and an extra function invocation?
Here's just another way to do it. You can have the function modify itself. In the case below, myfunction gets changed to a new one. This may not be exactly what you're looking for but I think it's useful to at least post this so you can see alternative ways to do things (and also: self modifying code can just be cool at times).
var myfunction = function() {
alert("This is the first time I'm executed");
myfunction = function() {
alert('Subsequent times');
}
}
myfunction(); // displays the alert 'This is the first time...'
myfunction(); // displays the alert 'Subsequent times'
myfunction();
Example: http://jsfiddle.net/jonathon/wntmB/
Related
Sorry for the rather beginner question. What's the differences of function usage between
$(document).keypress(function() {
//some code
});
and
var somethingElse = function() {
//some code
};
I know the latter is to create a function similar to Java's
public void somethingElse() {
//some code
}
but I always assume the former as anonymous function that act inside a method. Can someone shed me some light regarding this? Thanks.
The first one is a jQuery shortcut to create an event listener.
It's equivalent to:
document.addEventListener('keypress', function() {
// some code
});
More info: http://www.w3schools.com/jsref/met_document_addeventlistener.asp
Now, about named or anonymous functions, what's the difference between
var doSomething = function() {
// some code
};
and this?
function doSomething() {
// some code
}
There's no difference for the developer. Of course there's a difference on memory, but in javascript developers don't have to take care of it.
Actually for the case of an event handler or other techniques that use callback functions, you can pass an anonymous function or a previously declared one, it's exactly the same:
$(document).keypress(doSomething);
or
$(document).keypress(function() {
// some code
});
creates an anon function and passes it to the handler
creates an anonymous function and a variable that references it.
creates a named function - that is hoisted
the hoisted function becomes available to you at any line within your function scope, while the non-hoisted function will be undefined until the line where it is declared runs.
there is no difference between #2 and #3 (other than the hoisting) - some people think that the first one creates an object and the 2nd one is some magical thing, or a global function, but nope - they are both function objects within your scope.
The former is a callback, meaning some instructions that will be executed ONLY as soon as the keypress event in your example is triggered.
Thus, a function's name is not required.
Function expressions, the latter, is mostly used when adding an object's property acting as a method like:
var myObject = {};
myObject.sayHello = function() {
alert("Hello");
}
I am stumbling upon a problem that I have seen before, but that I couldn't solve before. I will likely stumble upon it again in the future, so please, someone explain it to me what is going on?
In the partial snippet of javascript below, I have a function that populates a screen, including an order combobox (twitter bootstrap). When I click on one of the order items in that combobox, it should invoke the function clsModCampaigns.blnCompaniesListReload().
For a reason that I don't understand, once inside the '$.each' iterator, the global object reference 'objModCampaigns' is lost? I get a successful alert '1', but not an alert '2'.
Within the $.each, I would like to use 'objModCampaigns.arrOrderBy' instead of 'this.arrOrderBy', but the $.each iterator only seems to work this way. Why is it working this way??
What is going on with 'this', or with variables/objects assigned in the root of the class with 'this'?
Is $.each just special??
function clsModCampaigns(objSetSystem, objSetModuleBase)
{
objModCampaigns = this;
arrOrderBy = {
intID: 'ID',
strName: 'Name'};
[...]
this.blnScreenCampaignInitialize = function (fncSuccess,fncError, intID) {
$.each(this.arrOrderBy, function (strFieldName, strFieldDescription) {
if(strFieldName != 'datDeleted' || objSystem.blnHasPerm("CAMPAIGNS_DELETED")) {
strOrderByID = "ulCampaignsCompaniesListOrderBy" + strFieldName;
$("#ulCampaignsCompaniesListOrderBy").append('<li>'+strFieldDescription+'</li>');
$("#"+strOrderByID).unbind("click").bind("click", function() {
alert("1");
objModCampaigns.arrCurrentShownCompanies.strOrderBy = strFieldName;
objModCampaigns.blnCompaniesListReload();
alert("2");
});
}
});
return true;
};
}
The code you have is
$.each(this.arrOrderBy, ...);
You want
$.each(arrOrderBy, ...);
The reason for it is the this context on that line is different because it is inside a new function this.blnScreenCampaignInitialize.
This is just a part of how JavaScript works
var message = "hello";
function welcome() {
console.log(message);
}
welcome(); // "hello"
P.S. use var
If you don't use var, you'll be attaching all of your vars to the global object.
function hello() {
foo = "bar";
console.log(foo);
};
hello(); // "bar"
console.log(foo); // "bar"
// Holy smokes! `foo` has escaped our `hello` function!
Compare that to
function hello() {
var foo = "bar";
console.log(foo);
}
hello(); // "bar"
console.log(foo); // ReferenceError: foo is not defined
// much better
Now let's see a terrible example
function a() {
b = 5;
return b;
}
function b() {
return "function";
}
console.log(a()); // 5
console.log(b()); // TypeError: number is not a function
This is happening because we didn't use var properly. We first define b as a function but after running a(), b is now set to 5. The second log statement is the equivalent of trying to run 5() because b is no longer a function.
P.P.S. it's pretty unconventional to prefix your vars with str, int, fnc, obj, or cls in JavaScript.
I understand you're a "VB guy" according to your comments, but that's no excuse for bringing your own conventions to the language. I see in your profile that you're fluent in Dutch, English, German, and French. I would recommend you treat learning programming languages much the same as spoken languages: each of them have their own explicit set of rules and conventions.
Here's a heap of free JavaScript books for you. I hope they can help you learn some more basics.
P.P.P.S. Overall, your function is really big as it is, and I can see you already truncated some of the code with your [...]. The whole thing could probably benefit from some better composition.
If you paste all of your code, maybe someone could help you better.
What is going on inside the $.each() ?
Regarding you question title, I'm trying to answer:
// each function in source
function (obj, callback, args) {
//...
}
Check the source of complete $.each function by yourself, you can see any function's source code just by typing the function name in the appropriate text box (the second on top).
Here in each function, the array/object passed in to the each function (the first argument) is being run through a loop and each value is being passed in to the callback (second argument) and that call back is getting executed like:
callback.apply(obj[i], args);
So, the passed callback in the each function is being executed each time the loop occurs ad the current value in the loop is passed as the argument of callback function along with the third argument args.
If your function function clsModCampaigns(){ //... } is a normal function then this inside this function points to global window object. so just use:
$.each(arrOrderBy, ...);
instead of
$.each(this.arrOrderBy, ...);
Because, arrOrderBy is within the direct scope so arrOrderBy is accessible directrly. For example:
function someThing()
{
var x = 'y'; //<-- this scope (everything inside someThing) is
// global for somethingElse inner function
function someThingElse)(x) //<-- possible to use directly
{
}
}
The keyword this behaves differently depending on the context. Check about this on MDN.
I wanted to have a method of adding functionality to pre-existing functions, so I made this:
Function.prototype.attachFunction = function(toAttach)
{
var func = this; //This is the original function, which I want to attack toAttach function to.
//Can I do this without wrapping it in a self-executing function? What's the difference?
func = (function()
{
return function()
{
func();
toAttach();
}
})();
return func; //Return the newly made function, not really important.
}
I paste this into the Google Chrome console, and there are no errors, however, it does not (or so it would seem) alter the original function at all.
f = function() {console.log("g");};
f.attachFunction(function(){console.log("New function!");});
f(); //Prints out just "g".
When attachFunction executes, it returns a function which executes func() and toAttach. However, if you change your code to be the following, it will attempt to execute both functions, where currently the old f is still called at the end.
f = function() {console.log("g");};
f = f.attachFunction(function(){console.log("New function!");});
f(); //Causes an infinite loop since calling func() is the same as calling this()
To merge two functions we need to wrap them the same way but not while extending Function
var func1 = function(){
console.log('g');
};
var func2 = function(){
console.log('New function!');
};
func1 = (function(f1,f2){
return function(){
f1();
f2();
}
}(func1, func2));
func1(); //Writes out both g and New function!
The reason I pass in func1, and func2 as parameters is to prevent the same problem of getting into an infinite loop. I want to maintain a reference to these functions at that point in time.
A helper function would then be the following
function combineFunctions(f1, f2){
return function(){
f1();
f2();
}
}
and would be used like this
var f = function() {console.log("g");};
f = combineFunctions(f,function(){console.log("New function!");});
f();
The attachFunction method you've set on the Function prototype is a higher-order function, or combinator, that accepts a function and returns a new function. It is inherited by any function created thereafter, as expected. However, when it is called it does not alter the state of f in any way, it simply produces a new function that calls f, or the calling function rather.
So, if you wanted to see both console.log messages, you simple need to call the function it returns, like so:
f.attachFunction(function(){console.log("hi")})();
or more simply:
f.attachFunction(f)();
Note that although functions are objects, the execution context (code) of f is not a property of f such that it can be manipulated directly, it is kept in an internal attribute.
Underscore.js' wrap() function should be quite close to what you want.
Currently, you're trying to call a variable as if it were a function (toAttach is a variable and you're smacking some parenthesis on the far side of it). Consider this: toAttach may CONTAIN a function, but that does not make it a function (much like a grocery store is not an apple). Instead you need to call the function contained within the variable.
There are several ways to do this (although only one or two apply here), none of the [right] ways involve eval() (life lessons).
Consider this thread. Pass the function name as a string and then use
window[toAttach]();
to call the function. It's a bit hacky, and lacks the finesse of passing the function as an object, but it works.
Alternatively (completely depending on your needs) you can bind the function to an event. If you're extra sneaky (and why not?) you can use
setTimeout(toAttach, 0);
Where toAttach is a reference to the actual function (again).
Finally, and best, I believe, is the Function.call() method. Using this, you can call a function stuffed in a variable, and even pass it a context for this.
toAttach.call([Context]);
Where [Context] is the context of the function (ie, what this refers to when inside of the function, in most cases it can be left blank to get the desired scope). I can't say I've tested it under your certain circumstances (thus why I have included it last), but I believe it should give you the results you're looking for.
Here's my attempt to achieve this, it is not clean as if it was entirely in the prototype but it works. There are probably better ways than mine.
var bindings={};
function execBindings(func_name) {
if (bindings[func_name] != undefined) {
for (var i=0;i<bindings[func_name].length;i++) {
bindings[func_name][i]();
}
}
}
Function.prototype.bind=function(action){
if (bindings[this.name] == undefined) {
bindings[this.name]=[];
}
bindings[this.name].push(action);
}
Then, to use the binding :
function f() {
alert("foo");
execBindings("f");
}
f.bind(function(){
alert("bar");
});
f.bind(function(){
alert("test");
});
f();
which results in 3 alerts, in the order thwy were binded to the function.
There are two problems I just found.
problem 1.
f = function() {console.log("g");};
f.attachFunction(function(){console.log("New function!");});
f();
It definitely doesn't work, cause attachFunction just wrap around your original function and return the wrapped, it doesn't change the original function, which means your f function is still f = function() {console.log("g");}
Problem 2.
If you reassign f with the result of attachFunction, an Maximum call stack size exceeded will occur. In the definition of attachFunction:
func = (function()
{
return function()
{
func();
toAttach();
}
})();
return func;
The func function call himself recursively.
Update
I prefer this approach.
Function.prototype.attachFunction = function(toAttach)
{
var that = this;
func = (function()
{
return function()
{
that();
toAttach();
}
})();
return func; //Return the newly made function, not really important.
}
f = function() {console.log("g");};
f = f.attachFunction(function(){console.log("New function!");});
f();
This question is more on javascript principle.
function done(){ console.log('done defined with `function done(){ ...`'); }
var done = function(){ console.log('done defined with `var done = ...`'); }
done = function(){ console.log('without `var`, just `done = ...`'); }
If defined right inside <script> tags, will they all do the same thing, right?
But if I place them in a closure (function(){ function definintion goes here }()) will any of these three types override either the globally defined function done() or any other done() functions that are defined inside their respective closures?
If the question above doesn't make sense, here's to rephrasing;
is the following code supposed to do the same thing in any JS runtime?
eval-ing code anywhere executes that particular code within the context or the global scope?
how can a setTimeout call be configured so that the code between its "quotes" executes to inside the scope where that particular setTimeout has been called (please see second timeout inside for below)? I mean is there any other way besides defining window.blabla functions and telling them to delete themselves after they run?
function done(d){ console.log('cha cha cha: '+d); }
setTimeout( function(){ done(2); }, 3500 );
for(i=0; i<10; i++){
(function(){
done = function(x){ console.log('done #'+i+' sais: '+x); }
setTimeout(function(){ done(i*2); },2500);
setTimeout(function(){ done(i*2); }.toString()+'(); ',2500);
}());
}
For the initial question on general behaviour:
var done = and function done do basicaly the same thing. They will shadow the outer definition in the inner scope but they will not replace it on the outer scope.
done = will set the corresponding done variable in scope or will create a global variable if such a variable does not exist and the program is not running in strict mode.
At a global level, outside any function, var done = and done = should work the same, but they work differently in IE if you try to use the variable in another script tag (stick to var = - its better anyway).
As for the very evil setTimeout and eval questions:
Yes, I guess this kind of stuff should be standardized enough to work the same everywhere. I would still test it anyway. (Or you could use a different solution, given how evil eval is)
eval runs code in the current scope (using deep black magic to do so). If you want to run code on the global scope you can use new Function instead.
In order to have the settimeout run the string in the curent scope you can add the eval yourself:
var done = function(d){ console.log('outer done', d); };
(function(){
var done = function(x){ console.log('inner done', x); };
setTimeout(function(){ done(1); }, 200); //inner done
setTimeout('done(2)', 400); //outer done
setTimeout(function(){ eval('done(3)'); }, 600); //inner done
}());
Once again, why are you eval-ing things in the setTimeouts? This all sounds profoundly evil!
There are differences between var done and done, because the latter implicates window.done and can be deleted therefore.
The statement done = foobar; will overwrite the next "done" variable in the scope chain. If there is a local var, it changes that, if there is a global one, it will overwrite that one, anf if not it will create a new global one.
All these will not affect any private variables in other scopes (closures).
One note on your first block. When you give a function a name as you have in the first line, that function name is parsed at compile time and available anywhere within the scope. If you simply assign a function to a variable, then that function (i.e., variable) is only available at runtime after the definition, even if you give it a name.
For example:
// this is valid
foo();
function foo(){ console.log("foo"); }
// this throws an error...
bar();
var bar = function (){ console.log("bar"); };
// ...and so does this...
baz();
var bat = function baz(){ console.log("bazbat"); };
// ...and this!
baz();
My understanding of closures is that they are essentially a function which uses a variable that you would assume would be out of scope. I guess heres an example I saw the other day:
function closureMaker(somearg)
{
var local_value = 7;
function funcToReturn(arg1, arg2)
{
return local_value + somearg + arg1 + arg2;
}
return funcToReturn;
}
var myClosure = closureMaker(6); //make the closure
myClosure(2, 3); //using it
Now the closure has local_value and even the original arg, somearg. But I dont get why these are helpful. What is the point of using the 'free' variable local_value or even more unknown to me, why would you use the argument of closureMaking function in your closure function?
I'm more interested in how this is used in javascript, Is this used a lot for AJAX requests and objects?
I got the what. I need the why.
One of the most practical and widely spread usage of closures is to implement private or privileged members for example, for example:
function Test (param) {
var secret = 3;
function privateMethod() {
//...
}
this.publicMember = param;
this.privilegedMember = function () {
return secret * param;
};
}
var foo = new Test(10);
foo.privilegedMember(); // 30
foo.secret; // undefined
The module pattern is also a good example that can use the same principle, e.g.:
var myModule = (function () {
var obj = {}, privateVariable = 1;
function privateMethod() {
// ...
}
obj.publicProperty = 1;
obj.publicMethod = function () {
// private members available here...
};
return obj;
}());
A common run-in is that in a for loop, you want to alert the number of the counter.
function addLinks () {
for(var i = 0; i < 5; ++i) {
var link = document.createElement('a');
link.appendChild(document.createTextNode('Link ' + i));
link.i = i;
link.onclick = function() { alert( i ) };
document.body.appendChild(link);
}
}
addLinks();
When you go to click on these links, it will alert 5 because the loop has already been done and i is equal to 5. We didn't "save" the state of i at the time of execution of the for loop.
We can make a closure to "save" that state:
function addLinks () {
for(var i = 0; i < 5; ++i) {
var link = document.createElement('a');
link.appendChild(document.createTextNode('Link ' + i));
link.i = i;
link.onclick = (function(i) { return function() { alert(i ) } })(i);
document.body.appendChild(link);
}
}
addLinks();
The i is bound to the self executing anonymous functions invoked within each increment in our loop. This way the state is saved and we get the right # on alert.
The example you're looking at is trying to show you how closures work. I think of closures as little pieces of code that you can pass around. The neat thing is that (free) variables in the closure are bound based on the current lexical scope. This is why local_value keeps the value 7 because that's what the value of local_value was when the closure was created.
Javascript implements closures via anonymous functions*, but keep in mind that technically, these are two separate concepts.
In the context of Javascript, closures (implemented as anonymous functions) are very helpful when you want to deal with things that happen asynchronously; a good example is, like you stated, AJAX requests where you cannot predict when you will get a response back from a server. In this case, you have an anonymous function called a callback that you initially define and pass in when you make the AJAX call. When the call successfully completes, your callback is called to process the result. Closures result in cleaner code since you can package behavior and logic inside them. It also helps you abstract the behavior our and separate concerns.
Another use for anonymous functions/closures is for event handling. When an event happens your event handler is called.
Like I had mentioned before, you can abstract behavior and logic and put it in a closure. But what really makes a closure so powerful is context. You can customize the behavior of your closure, depending on the environment in which it was created. This makes your function very versatile, because you are defining its arguments (which will influence its behavior) while you are creating it, instead of when you are calling it (with explicit parameters) during execution.
Here is a good article about closures in Javascript. It's long, but informative:
Javascript Closures
* As CMS mentioned, named functions will behave like anonymous functions because they will have access to variables that are defined in the same lexical scope (or anything up the chain). This is most evident in inner functions. But if you think about it, the same happens for any function; you have access to variables that have been defined in the global scope (i.e., global variables).
This is probably not quite what you are looking for but there is an excellent talk about closures for Java (how they should/could be implemented) that also goes into some examples on where you would want to use them
http://www.youtube.com/watch?v=0zVizaCOhME
Closures are an easy way to make functions that depend on parameters. Or to put it another way, to create a specific instance of a family of functions (read on if that's not clear) depending on some run-time value.
Javascript lets you pass functions around as first-class members; so for example, you could pass around a function that determines how to combine two integers by referring to it directly.
However, going one step further, a closure lets you create a "customised" version of a function, whose exact behaviour depends on some runtime variable (but which otherwise conforms to a framework).
For example, here's a function that will allow a curried addition:
function getAddNFunction(n)
{
function inner(operand)
{
return n + operand;
}
return inner;
}
Now if you call getAddNFunction(7), you get a function that adds 7 to an argument. If you call getAddNFunction(42.5), you get a function that adds 42.5 to the argument.
Hopefully this simple example clarifies the benefit of closures; they allow you to embed arguments in the function at creation time rather than them having to be passed in at execution time (after all, calling getAddNFunction(9)(2) is exactly the same as calling 9 + 2, except for the fact that the two arguments can be supplied at very different times).
So for instance you might want to return some kind of complex XML parsing function relative to some root element; a closure lets you embed that root element definition within the function itself, rather than depend on the caller having access to it whenever they want to execute the function.
If you are comnig from an OO world, closures allow you to create what are essentially private member variables, and methods, for your objects:
function Constructor(...) {
var privateVar = value;
function privateFunc() {
}
this.publicFunc = function() {
// public func has access to privateVar and privateFunc, but code outside Constructor does not
}
}
Douglas Crockford and javascript goodness
In addition to above closure helps in hiding some of the implementation detail.
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
alert(Counter.value()); /* Alerts 0 */
Counter.increment();
Counter.increment();
alert(Counter.value()); /* Alerts 2 */
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */
One more good article
Read this article on module pattern in javascript which heavily uses closures.