The following code is presented, in the book Head First jQuery.
function lightning_one(t) {
$("#lightning1").fadeIn(250).fadeOut(250);
setTimeout("lightning_one()", t);
}; // end lightning_one
It gets called with this line.
lightning_one(3000);
The observed behaviour is that the lightning fades in and out once, waits 3 seconds, fades in and out again, and then continues to fade in and out. Firebug shows no javascript errors.
I understand why I see what I see. I thought I would attempt to preserve the 3 second interval, so I changed this:
setTimeout("lightning_one()", t); // nothing in the brackets
to this:
setTimeout("lightning_one(t)", t); // t is in the brackets
When I refresh the page, the lightning fades in and out once. Firebug tells me that variable t is undefined.
My question is, if the variable t is not defined after my change, how did the command run without error before I changed it? It still has a variable named t.
More Info
Thank you everyone who wrote comments and answers. For the record, in the "end" folder, the code becomes this:
lightning_one();
function lightning_one(){
$("#container #lightning1").fadeIn(250).fadeOut(250);
setTimeout("lightning_one()",4000);
};
I haven't finished the applicable chapter yet so I don't know if the code change gets suggested later on. As mentioned earlier, this might not be the best book out there. However it's the one I bought and I am learning the fundamentals of jQuery from it.
Because the first argument of setTimeout as a string is eval-ed, meaning that it will looking into the outer scope of the function in which t is not defined. The first one is fine because you don't use any variables in the call, but the second is not because t is not defined outside the scope of the function. It is in fact local.
Advice: Don't use eval at all. In fact, you don't need the string argument. Use a function expression:
setTimeout(function() {
lightning_one(t);
}, t);
This will work:
setTimeout(function () { lightning_one(t); }, t);
I'm pretty sure invoking a function from a String (and letting it get evaluated) is a bad practice that should be avoided.
Related
I was writing a long polling script and ran into a too much recursion error which hung the browser. My goal is to call the same function every 1000ms using setTimeout(). Yes, I could use setInterval() but it is going to be a long polling script and will be waiting for a server response.
I fixed this by removing the () from the function I was calling within the same function.
My script looks like:
function messagePolling(){
console.log("polled")
setTimeout(messagePolling(),1000) // <--- removing `()` from the function works as intended
}
messagePolling();
What is the logic behind this? messagePolling is a function after all isn't it.
You're absolutely right - messagePolling is a function. However, messagePolling() is not a function. You can see that right in your console:
// assume messagePolling is a function that doesn't return anything
messagePolling() // -> undefined
So, when you do this:
setTimeout(messagePolling(), 1000)
You're really doing this:
setTimeout(undefined, 1000)
But when you do this:
setTimeout(messagePolling, 1000)
You're actually passing the function to setTimeout. Then setTimeout will know to run the function you passed - messagePolling - later on. It won't work if it decides to call undefined (the result of messagePolling()) later, right?
Written as
setTimeout(messagePolling(),1000) the function is executed immediately and a setTimeout is set to call undefined (the value returned by your function) after one second. (this should actually throw an error if ran inside Node.js, as undefined is not a valid function)
Written as setTimeout(messagePolling,1000) the setTimeout is set to call your function after one second.
When you type messagePolling you are passing the function to setTimeout as a parameter. This is the standard way to use setTimeout.
When you type messagePolling() you are executing the function and passing the return value to setTimeout
That being said, this code looks odd to me. This function just runs itself. It's going to keep running itself indefinitely if you do this.
Anywhere a function name contains "()" it is executed immediately except when it is wrapped in quotes i.e is a string.
Let me explain this a little better. I've just started learning JS and Jquery coming from learning java/c for a short while. I'm use to the functions (methods) in those languages and am having a difficult time understanding why certain functions are used in JS. I've read all sorts of tutorials and searched this site but the answers for "why anonymous functions are used" is different than what I'm looking for.
For example:
$(document).ready(function() {
$('div').hide();
});
Here with the use of jquery we are hiding the "div" elements with a function. Or here:
$('div').click(function() {
$('div').hide();
});
The same thing here except when we click on the div it hides it. But here's the thing I'm confused about - why does it need be on click, then a function running ".hide()" as opposed to just every time on click it just does "('div').hide();"
Or with the first piece of code you just want the 'div' elements hidden, why isn't it just simply hiding the elements with $('div').hide() - why is there the need of a function to do this? You don't need to call the function anywhere else. It just hides it when the document is ready, or with the first example, it hides when you click it.
I've seen this in the practice tutorials on codeacademy and other tutorial videos many times so far, where there are functions that I don't think are needed but are used.
Finally, even a function with a variable like this:
$('#add').click(
function() {
var value = $('#inp').val();
$('#shoplist').append('<li>' + value + ' </li>');
}
);
On click it adds a list element to the unordered list, but i don't understand what the need for function() {} is. .click() already makes something happen on click, we run code inside it to happen on click, why does it need a function() as well to make the code inside work?
why does it need be on click, then a function running ".hide()" as opposed to just every time on click it just does "('div').hide();"
You have to pass something to click.
That something is "The function you want to run when the click event happens"
If you instead did:
...click( $('div').hide() )
then you would:
Call hide() immediately (because that is what $('div').hide() does when it is evaluated)
Pass the return value to click.
The return value isn't a function, so it would either error or be ignored, and clicking would do nothing.
The function you pass to click doesn't need to be anonymous, but it does need to be a function.
This would be fine, for example:
function hide_div() {
$('div').hide();
}
...click(hide_div)
The .click function takes a function callback as a parameter. You're telling it what to run when the click event occurs.
You couldn't pass the code inside the anonymous function to the .click function because it is expecting a function callback.
Lines of code are run in functions, and lines of code are executed when they are called on. When you do this .click($('div').hide()), you're calling the function .hide() on $('div'), giving the result of this function to .click(), as opposed to giving this unevaluated line of code to the .click() function. Protip, whenever you see (), some function is executed unless this function is being declared. In this case, .click() is an execution of the function that has been declared as function click(var callback).
There does not exist a single language (that I can think of) where you can actually pass parsed lines of executable code to another function, that are not encapsulated by a method or function. This is simply so because lines of code do not have a type, or definition. How would you define a 'couple of lines of executable code' in a function somewhere?
I challenge you to define a function that does this, and I BET you will either create a function that accepts another function as a parameter, like click(var callback), OR that you will define some sort of parser that tries to parse the lines of code to executable JavaScript and then evaluate it, which is the same as an interpreter, which is what is used to run JavaScript to begin with.
I have a simple function that calls other functions:
function update() {
updateMissiles();
updatePlayer;
updateTurbines();
}
They are similar to each other in every way except updatePlayer will not run if I put brackets on the end of it. This doesn't break any code but I'm still curious why it does that?
I'm guessing there's an Exception in the updatePlayer method and since you're not calling it in the code you pasted above, you're not getting the Exception.
I would open up the Developer Tools for whatever browser you're using and see if there are any JavaScript Exceptions being thrown.
You are confused. updatePlayer; doesn't invoke the updatePlayer function. updatePlayer(); does. Something else is going on in your code.
Without knowing more it's impossible to pinpoint exactly, but as a best guess - in the scope of the update function, the updatePlayer variable is not a function.
Try logging or debugging your javascript to find out what is going on.
A function will run only if you put () after it's name.
If you don't put brackets you'll get the function's content.
For example if you have:
function updatePlayer(){ alert('This is a player');}
And call it without brackets:
alert(updatePlayer);
the alerted output will be
function updatePlayer(){ alert('This is a player');}
This is used if you want to use callback functions.
It's not the first time I've used setTimeout(), but I can't figure out what the problem is. The code part of the setTimeout() is executing correctly, but it is executing immediately without the delay. If anyone can see the problem, that would help. Here's the code:
if(token==1){
img1.src=ssImages[imgNum];
num1=0;
num2=10;
setTimeout('crossFade()',2500);
}
Are you sure this is the code? If it executes immediately there are usually two reasons:
The developer thought the time is specified in seconds - but 2500 is fine, that's 2.5 seconds.
He calls the function immediately (e.g. setTimeout(foo(), 1234));
But none of the reasons apply to your code so check the rest of the code if there are any other calls to that function.
Anyway, you should really pass a function instead of a string:
setTimeout(crossFade, 2500);
Or, if you need to specify any arguments:
setTimeout(function() {
crossFade(...);
}, 2500);
I agree with Theifmaster. The window. setTimeout method takes two arguments:
1) Function OR Expression
2) Time in ms
In your code you provide a string or an Expression :
setTimeout('crossFade()',....)
This is generally discouraged as with the use of eval. You should pass a function - either named:
setTimeout(crossFade,....)
OR as suggested anonymous:
setTimeout(function(){crossFade()},....
This is about all you can do to trouble shoot this code unless you provide an example ok jsfiddle for us to see the context this is called.
With objects especially, I don't understand what parts of the object run before initialization, what runs at initialization and what runs sometime after.
EDIT: It seems that parsetime is the wrong word. I guess I should have formulated the question "In the 2-pass read, what gets read the first pass and what gets read the second pass?"
A javascript file is run in a 2-pass read. The first pass parses syntax and collects function definitions, and the second pass actually executes the code. This can be seen by noting that the following code works:
foo();
function foo() {
return 5;
}
but the following doesn't
foo(); // ReferenceError: foo is not defined
foo = function() {
return 5;
}
However, this isn't really useful to know, as there isn't any execution in the first pass. You can't make use of this feature to change your logic at all.
Unlike C++, it is not possible to run logic in the Javascript parser.
I suspect that you're asking which code runs immediately and which code runs when you create each object instance.
The answer is that any code in a function that you call will only run when you call the function, whereas any code outside of a function will run immediately.
Not sure what you ask exactly so I'll just share what I know.
JavaScript functions are "pre loaded" and stored in the browser's memory which means that when you have function declared in the very end of the page and code calling it in the very beginning, it will work.
Note that global variables, meaning any variable assigned outside of a function, are not preloaded, so can be used only after being declared.
All commands outside of a function will be parsed in the order they appear.
JavaScript doesn't really have "runtime", it can only respond to events or have code executed via global timers. Any other code will be parsed and "forgotten".
While JavaScript's direct ancestor is Scheme, JavaScript didn't inherit macros, so the answer is fairly simple: there is never any code run during parse time.
Roughly speaking, Interpreter gets all variables and functions first, and then they get hoisted and executed.
For more detail, I hope these links might be helpful:
http://adripofjavascript.com/blog/drips/variable-and-function-hoisting
https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/