i am wondering if i can do some cleanup routines that will auto grab timeouts / intervals. consider this:
var timeout = setInterval(function dimitar() {
console.log("hi!");
}, 1000);
console.log(window);
i had a look through window and can't find any reference to the function that's been passed on. the reference to timeout is there, sure enough. so where does the function 'live' here? is it launching a new instance of the js interpreter to eval/run/keep the code? how can you access it in relation to the timeout uid?
i know i can curry the setInterval function and get it to always store the reference into an array which i can then loop through and clear, but am curious if there's a natural way of doing this
The function you create in your example is using a named function expression. The name is only available within the function. Otherwise, it behaves the same as an anonymous function: you haven't assigned it to a variable and since it's not a function declaration, it doesn't create a dimitar variable in the enclosing scope. The following article may be useful: http://yura.thinkweb2.com/named-function-expressions/
There's no eval-type thing going on: you've just passed in a reference to a function into window.setInterval. This function cannot be retrieved afterwards unless you've assigned it to a variable previously, or it was a reference to a function defined by a function declaration.
If you want to keep a reference to the function around, it's simply a matter of storing it in a variable first:
var dimitar = function() {
console.log("hi!");
};
window.setInterval(dimitar, 1000);
so where does the function 'live' here?
The timeout/interval queue is an internal implementation detail that's not accessible to content JavaScript. It retains a reference to the function passed in to setInterval, but it's not a reference that's visible to you.
Incidentally you should generally avoid using named inline function expressions. Although it's probably OK in this example code, IE's JScript has some serious basic bugs with them that can trip you up if you're not careful. Stick to named function statements (function dimitar() { ... } ... setInterval(dimitar, 1000)) or anonymous inline function expressions (setInterval(function() { ... })).
is it launching a new instance of the js interpreter to eval/run/keep the code?
No, it's the same interpreter and the queue could even be implemented in JavaScript. But the variables behind it are hidden away from the caller.
how can you access it in relation to the timeout uid?
The timeout ID is by design completely opaque. The only defined interface that can do anything with it is the clearTimeout/clearInterval call. There is no interface provided to get the function back from a timeout ID.
Related
I am learning JavaScript and becoming confused by the logic of the code examples. From codecademy. Why are there function set-ups in function calls?
I'm quite confused. I am moving from a simplified C-like langue.
The JavaScript example
var main = function(){
$('.article').click(function(){
$('.description').hide();
$(this).children('.description').show();
});
};
My understanding:
- main is a function name with a return type of var.
$('.article') is a element/object/or class object.
.click() is a call to a member function
But:
???:
.click(function(){
$('.description').hide();
$(this).children('.description').show();
});
This seems to be a newly on the spot created function to run When/If click() is activated or run.
The way I used to think is like this:
var *p_obj = $('.article');
var *p_obj = $('.description');
var do_click()
{
p_obj2.hide();
p_obj.children(p_obj2).show();
}
var main(){
p_obj.click(do_click);
}
Function main() looks at p_obj and calls click().
Click() evaluates to true/false and run the pointer_to function do_click().
Function do_click() looks at the p_obj2 and calls hide(), which performs an action of hiding the p_obj2.
Function do_click() also looks at p_obj and uses children to scope focus to p_obj2, then it runs show(), which preforms an action of displaying p_obj2.
I do realize my C-like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
The way this design looks seems like I must write extended functionality on-the-spot for every call to .click(), so if-then .click() is run on 3 different items, I'm creating different extended functionality for each object. But I would normally create a single function that varies it's internal execution based on the object or condition click() calls it by.
This set-up seems alright if the code a relatively simple or short, but on-the-spot functional seems like overworking for longer code and code where the functionality repeats but the objects change.
Am I thinking about JavaScript functions with-in functions correctly and is this a design goal of the langue to add long repeating extended functions with-in functions?
Here, you should understand 2 things:
passing functions as arguments
anonymous functions
The first concept is particulary important because callbacks are popular in JavaScript, so let me explain it for callbacks. Imagine we have 2 functions getStuffFromWeb and processStuff. You probably expect that they are used like this:
var result = getStuffFromWeb();
processStuff(result);
But the issue here is waiting for getStuffFromWeb may take some time (the server is busy), so instead they are usually used in a "when you finish, call this function" manner, which is:
var getStuffFromWeb = function(params,callback) {
...
callback(result);
};
getStuffFromWeb(someParams,processStuff);
Well, in fact the structure of getStuffFromWeb will be different, most likely something like this:
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
So when getStuffFromWeb is called, it starts to listen to response while the code after getStuffFromWeb(someParams,processStuff); goes on evaluating. When the response comes, it calls the callback function to process the data further using the procedure we have defined (processStuff).
The second concept is rather simple: you may of'course write smth like
var processStuff = function() {...};
var getStuffFromWeb = function(params,callback) {
requestObject.make_request(params)
.onSuccess(callback);
};
getStuffFromWeb(someParams,processStuff);
but if you use processStuff only once, why define a named function? Instead, you can just put the very same expression inside the onSuccess param like this:
var getStuffFromWeb = function(params) {
requestObject.make_request(params)
.onSuccess(function() {...});
};
getStuffFromWeb(someParams);
This looks exactly like if we took the value of processStuff and put it directly to the onSuccess's argument (and that's called anonymous function). And also we got rid of an extra argument of getStuffFromWeb.
So basically that's it.
Simple answer is that the second argument of click() requires a callback function.
This can be a named function passed as reference as in your p_obj.click(do_click); example or it can be an anonymous function with self contained logic. Anonymous functions are very common in javascript
It's the same thing just with 2 different ways of declaring the callback.
Note that the only time you would return anything from an event handler function would be to return false which effectively prevents the default browser event (url opening from href or form submit for examples) and stops event propagating up the DOM tree
main is a function name with a return type of var.
No. main is a variable which is assigned an anonymous function. The function name would go between the keyword function and the () containing the argument list.
It has no return statement so it returns undefined.
$('.article') is a element/object/or class object.
It is a call to the function $ with one argument. The return value is a jQuery object.
.click() is a call to a member function
Pretty much. In JavaScript we call any function that is the value of a property of an object as method.
This seems to be a newly on the spot created function
function () { } is a function expression. It creates a function, exactly like the one used to assign a value to main earlier. This question is worth reading for more on the subject.
When/If click() is activated or run.
The click function is called immediately. The new function is passed as an argument.
The purpose of the click function is to bind a click event handler so that when a click event hits the element later on, it will trigger the function passed as an argument.
I do realize my c -like example is wrong and odd. I realize my terminology is wrong or otherwise used incorrectly.
Leaving aside vagaries of syntax. The main difference here is that the click event handler function is that the event handler function is stored in an intermediary variable.
You can do that in JavaScript just as easily, and then reuse the function elsewhere in the code.
var main = function(){
function show_specific_description() {
$('.description').hide();
$(this).children('.description').show();
}
$('.article').click(show_specific_description);
show_specific_description.call($(".article").last()[0]);
};
main();
is this a design goal of the langue to add long repeating extended functions with-in functions?
No. Passing a function expression as an argument is a convenient way to be more concise when you don't want to reuse the function. It's not the only way to pass functions about.
main is currently a function.
It is possible to be overwritten (even to a different type). var is not the return type, it's a statement that main is a variable.
All values should be declared as variables, within the highest scope you intend them to be used (in JS, scope typically means functions, not blocks).
You have the right idea, suspecting that the function gets passed in, and called at a later point in time (and this is actually one of the harder parts for people to get, coming from certain other languages). You'll see this behaviour all through JS.
One key thing to keep in mind in this language (you haven't hit it yet, but you will) is that JS is lexically scoped.
function getInnerX () {
var x = 5;
function getX () {
return x;
};
return getX;
}
var x = 10;
var getX = getInnerX();
console.log(getX()); // 5
The function getX inside of getInnerX has access to the references around it, at the point where it's defined (not where it's called), and thus has live access to the inner x, even if its value changes over time.
This will be another important piece of understanding what you see going on in the language, especially in the case of callbacks.
When I call a function, a local scope is erected for that call. Is there any way to directly reference that scope as an object? Just like window is a reference for the global scope object.
Example:
function test(foo){
var bar=1
//Now, can I access the object containing foo, bar, arguments and anything
//else within the local scope like this:
magicIdentifier.bar
}
Alternately, does anyone have a complete list of what is in the local scope on top of custom variables?
Background: I'm trying to get down to a way of completely shifting to global scope from within a function call, the with statement is a joke, call works a little better, but it still breaks for anything declared in function scope but not in global scope, therefore I would declare these few cases in global scope, but that requires me to know what they are. The IE function execScript makes a complete shift, but that only solves the problem for IE.
Note: To anyone loading JavaScript dynamically, setTimeout(code,1) is a simple effective hack to achieve global scope, but it will not execute immediately.
No, there's no way to reference the variable object of the execution context of a function binding object of the variable environment of the execution context (that's what that thing is called [now; hence the strikethrough]; details in §10.3 of the specification). You can only access the limited view to it you get with arguments (which is very limited indeed).
Usually when I've wanted to do this, I've just put everything I wanted on an object and then used that (e.g., passed it into a function). Of course, any functions created within the context have access to everything in scope where they're created, as they "close over" the context; more: Closures are not complicated.
I know this is hugely late, and you're probably not even slightly interested any more, but I was interested in the feasibility of this too and you should be able to make a work around of some sort using:
(function(global) {
var testVar = 1;
global.scope = function(s) {
return eval(s);
}
})(this);
then running:
scope('testVar'); // 1
returns the variable from within the closure. Not particularly nice, but theoretically possible to wrap that in an object, perhaps using some validation and getters and setters if you needed?
Edit: Having re-read the question, I assume you'd want to access it without having to specify a function in the scope itself, so this probably isn't applicable. I'll leave this here anyway.
Certain versions of Netscape had a magic property in the arguments object that did what you're looking for. (I can't remember what it was called)
What about something like this?
<script type="text/javascript">
var test = {
bar : 1,
foo : function () {
alert(this.bar);
}
}
test.foo();
</script>
You don't need a keyword to reference a variable in the local scope, because it's the scope you're in.
I have read number of answers in SO, however I cannot come up a clear explanation in my mind about variable life time in javascript. Generally answers are about hoisting/shadowing which is not the case here imo. For instance, we often write those kinds of scripts along with jQuery;
function getSomeData() {
var $container = $('#someContainer');
$.get('/url', function(data) {
$container.html(data);
});
}
Now, my main question is how does $container variable remain available to the anonymous callback function? I know, when execution comes up to $.get, get immediately returns and getSomeData returns eventually, though get may return any time in future. Hence I'm forced to think that getSomeData in fact remains in function call stack in order to provide $container variable to callback function, because to my knowledge if a variable is not found in the scope it is used, interpreter looks it up in parent scope (to the global scope). Here are the side questions:
Does this kind of pattern causes performance degradation?
If I change anonymous function to a declared function and use like;
var callback = function(data) {
$container.html(data);
}
$.get('/url', callback);
is there any advantage of this usage (except for debug purposes, and readability)?
If there is no function call stack involving here, where is $container stored until the promise resolves? Plase note that also this nesting is possible:
function getSomeData() {
var $container = $('#someContainer');
var replaceHtml = function(data) {
$container.html(data);
}
$.get('/url', function(data) {
replaceHtml(data);
});
}
Please give a clear explanation of that, thanks!
Now, my main question is how does $container variable is available to anonymous callback function?
...Hence I'm forced to think that getSomeData in fact remains in function call stack in order to provide $container variable to callback function, because to my knowledge if a variable is not found in the scope it is used, interpreter looks it up in parent scope (to the global scope).
You're really close to understanding this. Just a couple of corrections and clarifications will get you there.
It has nothing to do with the function call stack. You're quite right that getSomeData returns before the callback is run. That means it comes off the stack, just like normal. However, its local variables and such
live on, even though the function has returned. Why? Because the callback has an indirect reference to them.
When a JavaScript function is called, an object is created (theoretically) which is the execution context for that call. That context contains a variety of things, including an object called the variable environment that contains the arguments and variables and such related to the call. Any function created within the context keeps a reference to that context's variable environment object, and so has access to them even though the function has returned. These functions are called closures because they "close over" the context in which they were created.
So when the callback refers to the $container variable, the JavaScript engine looks in the callback's own context and its variable environment and, not finding $container there, looks at the next containing environment. It finds $container there and uses it.
Let's break it down into steps. Please note there's hand-waving here, the spec contains the details.
Something calls getSomeData
The engine pushes the return address on the stack
The engine creates an execution context for the call
The engine creates a variable environment for the context, populating it with the arguments, local variables, etc.
The engine runs the code in the function
Part of that is creating the callback function, which is given a reference to the variable environment object
Another part is handing that function reference to $.get, which keeps it for a while
Code exectuion "falls off" the end of the function, so the engine pops the return address from the stack and carries on
Some time later, $.get calls the callback through the reference to it that it kept
A new context and variable environment are created for the call to the callback
Callback code runs, looking up things in its own variable environment and also the environment in which it was created (for $container)
Code execution "falls off" the end of the function, the engine pops the stack, $.get drops its reference to the function
Since the function has nothing referring to it, it's eligible for garbage collection
At some point, the engine's GC algorithm disposes of the function, and so the function no longer refers to the variable environment object from the call to getSomeData, and so that object is eligible for GC.
At some point, the engine disposes of the variable environment object
Now, other than side-effects (like actually using the information from $.get), all is cleaned up
Does this kind of pattern causes performance degradation?
Not in and of itself, no. If you create a function and keep it around, then since it keeps the variable environment where it was created around, that can cause memory impact. But once you release the function (in this case, once $.get has called it and dropped its reference to it), then the function can be GC'd, and the variable environment (and its contents) can be GC'd.
In the above I talk about a lot of objects and garbage collection, but of course JavaScript engines can and do a lot of optimization around this. It's a big part of why modern engines are so much faster than the old ones were. (Just one part, but part.)
If I change anonymous function to a declared function and use like;
var callback = function(data) {
$container.html(data);
}
$.get('/url', callback);
is there any advantage of this usage (except for debug purposes, and readability)?
No.
If there is no function call stack involving here, where is $container stored until the promise resolves?
See above.
If have a callback that is activated repeatedly such as the following...
Template.foo.rendered = function() {
$(this.firstNode).droppable({
// other arguments
drop: function() {
// some really long function that doesn't access anything in the closure
}
});
}
Should I optimize it to the following?
dropFunction = function() {
// some really long function that doesn't access anything in the closure
}
Template.foo.rendered = function() {
$(this.firstNode).droppable({
// other arguments
drop: dropFunction
});
}
In this case, the rendered callback is a Meteor construct which runs asynchronously over a DOM node with template foo whenever they are constructed; there can be quite a few of them. Does it help to declare the function somewhere in a global closure, to save the Javascript engine the hassle of keeping track of an extra local closure, or does it not matter?
I don't believe that in modern browsers that there will even be a difference. When creating a closure object, V8 determines what variables your function uses, and if you don't use a variable it won't put it in the closure object(I read this somewhere online a while back, sorry I can't find the link*SEE BELOW*). I assume any browser that compiles JavaScript would do the same.
What will be optimized is the creation of the function. In the second example the drop function is created at the same time as the rendered function, in the first it's re-created every time the rendered is called. If this was in a long for loop that might be worth optimizing.
I personally think the first example is a lot easier to read and maintain. And as I said in a comment on the question you(or the person editing this code in the future) could accidentally overwrite the function variable(in an event handler or something) and you could have a hard to find bug on your hands. I would suggest saying with number 1, or wrapping everything in a self-executing function so dropFunction has a smaller scope and less chance of being overwritten, like so:
(function () {
var dropFunction = function() {
// some really long function that doesn't access anything in the closure
}
Template.foo.rendered = function() {
$(this.firstNode).droppable({
// other arguments
drop: dropFunction
});
}
})();
EDIT: I found the link, it was actually in a blog post about a closure memory leak in Meteor!
http://point.davidglasser.net/2013/06/27/surprising-javascript-memory-leak.html
Here's the portion I mentioned:
JavaScript implementations (or at least current Chrome) are smart enough to notice that str isn’t used in logIt, so it’s not put into logIt’s lexical environment, and it’s OK to GC the big string once run finishes.
I'll start this by saying I don't know anything about meteor :/ but if I'm understanding what happens correctly, basically:
Template.foo.rendered
Gets called repeatedly. When that occurs, you construct and object + define a new function on it "drop" which is eventually invoked. If that is the case, you are better off from a performance perspective defining drop once at parse time. But the benefit probably depends on how often rendered is called.
As for why - I posted something similar here:
Performance of function declaration vs function expressions in javascript in a loop
And I think #soktinpk's answer I think is a great summary.
If you look at the jsperf in the above link it may not initially seem directly applicable, but if my assumed statements above are true it is in fact is - because the question at hand boils down to how expensive is to define a function at runtime vs parse time and are you defining this function at runtime over and over again.
If you look at the performance of the loops where a function is defined at runtime vs the loops where functions are defined at parse time (or defined at parse time and hoisted), the parse time loop run significantly faster.
I believe that the equivalent of what meteor is doing in your example is probably something like this jsperf: http://jsperf.com/how-expensive-is-defining-a-function-at-runtime2
What I have done here is created two loops that simulate your scenario being invoked over and over again. The first invokes a function that creates and object and function and passes it to another function for invocation.
The second creates and object that references a function and passes it to another function for invocation. The difference in performance looks significant (58% in chrome).
When I call a function, a local scope is erected for that call. Is there any way to directly reference that scope as an object? Just like window is a reference for the global scope object.
Example:
function test(foo){
var bar=1
//Now, can I access the object containing foo, bar, arguments and anything
//else within the local scope like this:
magicIdentifier.bar
}
Alternately, does anyone have a complete list of what is in the local scope on top of custom variables?
Background: I'm trying to get down to a way of completely shifting to global scope from within a function call, the with statement is a joke, call works a little better, but it still breaks for anything declared in function scope but not in global scope, therefore I would declare these few cases in global scope, but that requires me to know what they are. The IE function execScript makes a complete shift, but that only solves the problem for IE.
Note: To anyone loading JavaScript dynamically, setTimeout(code,1) is a simple effective hack to achieve global scope, but it will not execute immediately.
No, there's no way to reference the variable object of the execution context of a function binding object of the variable environment of the execution context (that's what that thing is called [now; hence the strikethrough]; details in §10.3 of the specification). You can only access the limited view to it you get with arguments (which is very limited indeed).
Usually when I've wanted to do this, I've just put everything I wanted on an object and then used that (e.g., passed it into a function). Of course, any functions created within the context have access to everything in scope where they're created, as they "close over" the context; more: Closures are not complicated.
I know this is hugely late, and you're probably not even slightly interested any more, but I was interested in the feasibility of this too and you should be able to make a work around of some sort using:
(function(global) {
var testVar = 1;
global.scope = function(s) {
return eval(s);
}
})(this);
then running:
scope('testVar'); // 1
returns the variable from within the closure. Not particularly nice, but theoretically possible to wrap that in an object, perhaps using some validation and getters and setters if you needed?
Edit: Having re-read the question, I assume you'd want to access it without having to specify a function in the scope itself, so this probably isn't applicable. I'll leave this here anyway.
Certain versions of Netscape had a magic property in the arguments object that did what you're looking for. (I can't remember what it was called)
What about something like this?
<script type="text/javascript">
var test = {
bar : 1,
foo : function () {
alert(this.bar);
}
}
test.foo();
</script>
You don't need a keyword to reference a variable in the local scope, because it's the scope you're in.