In JavaScript functions are objects, and as Mr. Crockford writes the two notations below are equivalent:
function funct1(){};
var funct = function funct1(){};
So when I treat an individual function (not the global object) as a variable that is an object, it works, and my example is illustrated below:
function testFunction(){
var variable = "value";
}
testFunction.value1 = "value1";
function testFunction2(){
var variable = "value2";
}
alert(testFunction.value1); //returns "value1"
setTimeout(function(){
alert("setTimeout 5001: " + testFunction.value1); //returns "value1"
alert("setTimeout 5001 function2: " + testFunction2.value1); //returns "undefined"
},5001);
I used a setTimeout to ensure the function execution is finished (maybe the time set is not long enough for a 'real' test?).
This looks like an interesting way to store values outside of function execution (as in once a function has terminated and a value that it calculated is intended to be retrieved). Would this be correct? Is it an established coding practice?
One issue I see is there is potential for memory leaks, as once large amounts of data start to get stored and forgotten about these will hang around and cause the script to be sluggish. Is this true? Is there not the same problem with object variables (as in variables with key:value pairs)?
I have not seen this used before.
I used a setTimeout to ensure the function execution is finished (maybe the time set is not long enough for a 'real' test?).
This is unnecessary. Your example code will be executed synchronously and you don't need to "wait" for anything.
This looks like an interesting way to store values outside of function execution. Is it an established coding practice?
Yes. This is often done for static values that are related to the function, which should be publicly accessible and not pollute the scope. Very common on constructors or "invokable modules".
as in once a function has terminated and a value that it calculated is intended to be retrieved. Would this be correct?
No. The value that a function has calculated should be returned. Storing it in a static place is a very bad idea, as multiple invocations of the function might interfere with each other.
One issue I see is there is potential for memory leaks, as once large amounts of data start to get stored and forgotten about these will hang around and cause the script to be sluggish. Is this true?
Yes. But you store it on non-collected properties only if you want it not to be forgotten. You simply wouldn't do this with large data.
Is there not the same problem with object variables (as in variables with key:value pairs)?
Those are called properties, but yes. The only difference is that function objects usually live longer than plain objects (due to their usage, they're not handled differently by GC)
Related
I have read in several places such as here about "Access Links" and "The Display Method" for looking up non-local variables. However, none seem to touch on the complicated situation like in JavaScript where you can have functions inside of functions, and return those functions from functions, all the while keeping alive the "internal scope" of those functions.
Here is a complicated nested function.
let m = foo()
m()
m()
function foo() {
let x = 10
function bar() {
let y = 2 ** x
function hello() {
let z = 30
function another() {
// PLACE_2
let q = x + y + z
function nested() {
q += (17 * x) - (3 * z)
// PLACE_1
console.log(q)
console.log(w)
}
return nested
}
// PLACE_3
let w = another()
return w
}
return hello
}
// PLACE_4
let a = bar()
let nested = a() // hello returns another
nested()
nested()
return nested
}
At PLACE_1, we are using variables x/z/q, but not y/a/nested. Basically we create all these lingering objects in the scope tree.
How does an activation record with "Access Links" or "Display Method" work in a situation like this? I am used to having functions call other functions, but not keep the environment of past functions around. How do these work in a complex system like this with scopes lingering?
I am trying to implement a compiler and am currently stuck on how to actually implement the Activation Records. I can do it where the activation records are a simple parent/child relationship based on calling order, but I don't see how to make it work with a situation like this. I want to have a sort of variable lookup mechanism, but I don't know what needs to be stored in a situation like this.
Reading something like this doesn't give any insight into real-world situations like this, how it's modeled under the hood.
Displays can only be used if the semantics of the language don't allow non-local variables to outlive their original scope, since the display is basically an efficient eay to find an activation record on the stack. If you want to implement true closures, you'll need to use a different mechanism which involves heap-allocation of enclosed variables. (Unless you can prove that the enclosed variable never escapes. That's often the case, but it can be hard to prove.)
AUUI, Javascript retains the entire activation record of the function call which created the closed variable. But that's dependent on the semantics of the language, and unnecessarily keeping active links to other variables in the activation record prevents them from being garbage collected in a timely manner. It should only be necessary to keep links to the variables actually being enclosed.
Note that there are two distinct cases (again, this depends on language semantics). In the simple case, the captured variable is immutable (although it might contain a mutable value). In that case, you can capture the value by adding it as a data member in the closure. (The closure object itself needs to be heap-allocated but you don't need to do that until the closure is actually created, which might never happen.)
In the more complicated case, the variable itself is mutable and potentially mutated by the inner function [Note 1]. In that case, the variable itself must be "boxed"; that is, enclosed in a container which is used as a handle for the variable. But the mutation might happen before the variable's scope terminates, in which case the change needs to be visible in that scope. If the variable is boxed, the outer function needs to be aware of that because access to the variable is indirect. So boxing the variable onto the heap is a cost which must be paid before it is known to be necessary (depending on the quality of the escape analysis).
That's where the Lua implementation is interesting, at least. It manages to avoid heap-allocating the box in many cases, but there is an additional cost when it does so. That seems to work out well for Lua use cases but I don't know whether it would be a good solution in your case.
Notes:
There's a very common case where a variable is mutable because its value cannot conveniently be computed in a single initialisation expression, but all mutations occur before the variable is captured. Such a variable can be treated as though it were immutable (or as though it was computed and then made the value of a different variable with the same name). That case is fairly easy to detect. (There are also variables whose last mutation is after capture but before the first invocation of a capturing function. Those can also usually be detected.) These variables can be captured as though they were constant, just putting the value into the closure.
Informal surveys indicate that the vast majority of captured variables are either constant or constant-after-capture, which could considerably reduce the need for heap-allocated boxes.
I read that every function has its own stack, which means that when the function ends its variables are no longer kept into the memory. I read also that objects are returned by reference.
Consider this example:
function getObject() {
var obj = {name: "someName"};
return obj;
} //At the end the locals should disappear
var newObj = getObject();// Get reference to something that is no longer kept in the stack,
console.log(newObj);//
So if the returned value by the function is a reference to an object that no longer exists (in the stack), how are we still getting the right value? In C (language) to return a pointer to a local variable is insane.
First, a quick disclaimer: There's a difference here between the theory and the optimized process that modern JavaScript engines actually perform.
Let's start with the theory:
The object isn't on the stack, just the variable that contains the reference to the object. The object exists separately, and is created in the heap. So in your example, just before the function returns, we have this in memory:
+−−−−−−−−−−−−−−−−−−+
| (object) |
+−−−−−−−−−−−−−−−−−−+
[obj:Ref11254]−−−−−>| name: "someName" |
+−−−−−−−−−−−−−−−−−−+
obj, the variable, contains a reference to the object (Ref11254, though of course that's just a conceptual number, we never actually see these). When your function returns, the content of obj (Ref11254) is returned, and obj (the variable) disappears along with the rest of the stack. But the object, which exists separately, continues to exist as long as something has a reference to it — in your case, the newObj variable.
In practice:
As an optimization, modern JavaScript engines frequently allocate objects on the stack (subject to engine-specific size constraints). Then, if the object is going to continue to live after the function terminates and the stack is cleaned up, they copy it into the heap. But if the object isn't going to survive (that is, no reference to it has been kept or is being returned), they can let it get cleaned up along with the stack. (Why? Because stack allocations and cleanup are really fast, and a lot of objects are only used locally in functions.)
It's worth noting that the same question arises for variables if the function creates a function:
function getFunction() {
var x = 0;
return function() {
return x++;
};
}
var f = getFunction();
console.log(f()); // 0
console.log(f()); // 1
console.log(f()); // 2
Now it's not just that the function getFunction returns (which is an object) survives, but so does x! Even though variables are "on the stack," and the stack gets reclaimed when getFunction returns. How is that possible?!
The answer is that conceptually, local variables aren't on the stack. Putting them on the stack is an optimization (a common one). Conceptually, local variables (along with a few other things) are stored in an object called a LexicalEnvironment object which is created for the call to getFunction. And conceptually, the function getFunction returns has a reference to that LexicalEnvironment object, and so it (and the variables it contains) continues to live on even after getFunction returns. (The function getFunction returns is called a closure because it closes over the environment where it was created.)
And sure enough, in practice modern JavaScript engines don't really do that. They create variables on the stack where it's quick and easy to clean them up. But then if a variable is going to need to live on (like x needs to in our example above), the engine puts it (and any others that it needs to keep around) into a container in the heap and has the closure refer to that container.
More about closures in this question's answers and on my anemic little blog (using slightly outdated terminology).
Because the garbage collector is clever than that! Simply put, if the object has active references then it isn't removed. Variables created within the function and not returned are lost when the function ends (unless you've created async calls which use them) but because they then don't have any active references.
See, for example, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
I've seen this syntax for creating an anonymous constructor function in JavaScript:
var Application = Application || {};
!function(window, Application) {
Application.property = {/*...*/}
Application.method = function(){/*...*/}
}(window, Application);
I want to understand what the following parts here:
What is the advantage of using first line (i.e. var o = o || {};) vs just stating var o = (function(){})();?
Why ! is used in front of function?
Why would I pass window or Application as parameters when they are global object?
Is this the most convenient way for anonymous constructor function and how is this better than:
4a)
var Application = {
property: {},
method: function(){}
}
or 4b)
var Application = (function() {
var method = function(){/*...*/}
return {method:method};
}());
The first line is to ensure that Application always exists, and is generally used in cases where it's expected that Application already should exist, and the function just augments the existing object. If it doesn't exist, this makes sure that we don't get an error for accessing properties of undefined. Your examples are only equivalent in the case where Application does not yet exist. In all other cases, your code will obliterate the existing Application, which is almost certainly not the intent.
The comment from Vatev explains what the ! does. It's another syntax for making the function in question become a self executing anonymous function. (Incidentally, it also takes the return value of the function - which is currently undefined, and flips its truthyness, so it evaluates as true. Since the result isn't stored in any variable, though, that's clearly not the purpose.)
Finally, why pass window and Application into the function and use it there? This is a safety feature, in case other code changes window or Application later on. It guarantees that within the anonymous function, window and Application are exactly what you expect it to be. In the shorthand example you gave, this may appear to not matter - after all, why protect these variables if you're using them immediately and not storing them? In many cases, you return something from this function, and then window and Application would be stored in the closure, so you'd retain the variables. It makes it safe from people who later on decide to say Application = {...}.
I don't know all of the answers but I'll try to answer what I can.
Using var Application = Application || {}; simply means that you are dealing with scope. If the "Application" variable has already be defined, it will just mean that it inherits and is now available in the current scope. If not, the "||" part (means OR) means that it will be created as an empty object. You are dealing with creating an object and then acting on it, not just having the result given back raw. That's why you shouldn't use "o = (function() {...});". "o" would then be the result of the function and not the object.
The use of "!function" causes it to be treated as an expression, but this can be tricky because you may have to think in opposites. E.g. !null means you are checking that it isn't null, not that you are checking for it to be null.
Passing in the window and Application objects deal with scoping, again. It is explicitly passing them into the function, then returning them at the end. Think of this as putting clothes in the washing machine. You put them in, stuff can happen, then you get them back out. It's a really crude idea and isn't the best example, but it's how I thought of it a while back. You put clothes in, call then rinse function, then soap function, then rinse again, then spin to drain water.
Hopefully someone else can answer that, I'm not sure what the differences are.
Since two answers so far neglected these two details: A pattern used by libraries like jQuery is using the following two parameters:
(function (window, undefined) {
window.myPlugin = ...;
})(window);
There are two things going on here:
undefined is specified as a parameter, but not passed in. This way, undefined is guaranteed to have th expected value within the inner scope. This is only necessary for older browsers which allowed overwriting undefined (though it has always been considered bad practice to do so – it's just what libraries like jQuery do to avoid other code interfering with their code).
Aliasing a global object like window within the scope allows the code to be minified more (also works for undefined). Obviously, the more references you have to the aliased object(s), the more you will save:
.
(function(w,u){w.myPlugin=...;w.somethingElse=...;if(whatever===u){return;}})(window);
compared to
(function(){window.myPlugin=...;window.somethingElse=...;if(whatever===undefined){return;}})();
You won't save much with window since typically you don't wanna clutter the global object up anyway. But aliasing undefined can save you quite some space.
I'm trying to wrap my head around private variables in Javascript, temporary variables, and the GC. However, I can't quite figure out what would happen in the following situation:
MyClass = function() {
this.myProp = new createjs.Shape();
var tempVar = this.myProp.graphics;
tempVar.rect(0, 0, 10, 100);
tempVar = null;
var isDisposed = false;
this.dispose = function() {
if (isDisposed) return;
isDisposed = true;
}
}
var anInstance = new myClass();
My intention was to have isDisposed represent a private status variable, and tempVar be a use-and-throw variable.
Would tempVar get marked for GC? Would isDisposed be marked for GC too? How is the GC to know when I'm trying to declare a temporary variable meant for disposal, and when I'm trying to have a private variable within the object?
I tried to test the following in Chrome, and it seems as if tempVar never gets GC-ed as long as an instance of myClass exists. So I'm not sure what to believe now. I am incredulous that every single local variable that I create for temporary usage will exist in scope for the lifetime of the object.
Javascript does not have strongly typed objects. By setting tempVar to null, you're not declaring that you don't want to use it any more or marking it for collection as in Java or C#, you're merely assigning it a (perfectly valid) value. It's a trap to begin thinking that just because you made tempVar an "instance" of an object, that the variable is in fact an object and can be treated as such for its whole lifetime.
Basically, variables are just variables in Javascript. They can contain anything. It's like VB or VBScript in that regard. Scalars do undergo boxing in many cases (as in 'a|c'.split('|') making the string into a String) but for the most part, forget that. Functions are first-class objects meaning you can assign them to variables, return them from functions, pass them as parameters, and so on.
Now, to actually destroy something in Javascript, you either remove all references to it (as in the case of an object) or, in the case of an object's properties, you can remove them like this:
delete obj.propertyname;
// or //
delete obj[varContainingPropertyName];
To expand on that point, the following two code snippets achieve identical results:
function abc() {window.alert('blah');}
var abc = function() {window.alert('blah');}
Both create a local variable called abc that happens to be a function. The first one can be thought of as a shortcut for the second one.
However, according to this excellent article on deleting that you brought to my attention, you cannot delete local variables (including functions, which are really also local variables). There are exceptions (if the variable was created using eval, or it is in Global scope and you're not using IE <= 8, or you ARE using IE <= 8 and the variable was created in Global scope implicitly as in x = 1 which is technically a huge bug), so read the article for full details on delete, please.
Another key thing that may be of use to you is to know that in Javascript only functions have scope (and the window in browser implementations or whatever the global scope is in other implementations). Non-function objects and code blocks enclosed in { } do not have scope (and I say it this way since the prototype of Function is Object, so functions are objects too, but special ones). This means that, for example, considering the following code:
function doSomething(x) {
if (x > 0) {
var y = 1;
}
return y;
}
This will return 1 when executed with x > 0 because the scope of variable y is the function, not the block. So in fact it's wrong and misleading to put the var declaration in the block since it is in effect (though perhaps not true practice) hoisted to the function scope.
You should read up on closures in javascript (I cannot vouch for the quality of that link). Doing so will probably help. Any time a variable's function scope is maintained anywhere, then all the function's private variables are also. The best you can do is set them to undefined (which is more "nothing" than "null" is in Javascript) which will release any object references they have, but will not truly deallocate the variable to make it available for GC.
As for general GCing gotchas, be aware that if a function has a closure over a DOM element, and a DOM element somewhere also references that function, neither will be GCed until the page is unloaded or you break the circular reference. In some--or all?--versions of IE, such a circular reference will cause a memory leak and it will never be GCed until the browser is closed.
To try to answer your questions more directly:
tempVar will not be marked for GC until the function it is part of has all references released, because it is a local variable, and local variables in Javascript cannot be deleted.
isDisposed has the same qualities as tempVar.
There is no distinction in Javascript for "temporary variables meant for disposal". In newer versions of ECMAScript, there are actual getters and setters available, to define public (or private?) properties of a function.
A browser's console may provide you with misleading results, as discussed in the article on deleting with Firefox.
It's true, as incredible as it may be, that in Javascript, so long as a variable exists within a closure, that variable remains instantiated. This is not normally a problem, and I have not experienced browsers truly running out of memory due to tiny variables lying around un-garbage-collected. Set a variable to undefined when done with it, and be at ease--I sincerely doubt you will ever experience a problem. If you are concerned, then declare a local object var tmpObj = {tempVar: 'something'}; and when done with it you can issue a delete tmpObj.tempVar;. But in my opinion this will needlessly clutter your code.
Basically, my suggestion is to understand that in coming from other programming languages, you have preconceived notions about how a programming language ought to work. Some of those notions may have validity in terms of the ideal programming language. However, it is probably best if you relinquish those notions and just embrace, at least for now, how Javascript actually works. Until you are truly experienced enough to confidently violate the advice of those who have gone before you (such as I) then you're at greater risk of introducing harmful anti-patterns into your Javascript code than you are likely to be correcting any serious deficit in the language. Not having to Dispose() stuff could be really good news--it's this nasty pervasive task that Javascript simply doesn't require from you, so you can spend more time writing functionality and less time managing the lifetime of variables. Win!
I hope you take my words as kindly as they are meant. I don't by any means consider myself a Javascript expert--just that I have some experience and a solid competence in understanding how to use it and what the pitfalls are.
Thanks for listening!
var name = function(n) {
var digits = ['one','two','three','four'];
return digits[n];
}
var namenew = (function() {
digits = ['one','two','three','four'];
return function(n) {
return digits[n];
}
}());
Both the versions result in the same output, however it is said that the second version is much faster than the first version.
As I understand, first version executes the function everytime where as the second version stores the result of execution. That is what confuses me as a functional/regular OOPS programmer.
How can one save a function with its inner context? What is happening under the hood? Can some one pls clarify?
The real answer to that question would be about 3 pages long. But I try to make it as short as possible. ECMA-/Javascript is all about Execution Contexts and Object. There are three basic types of Context in ECMAscript: Global context, Function contexts and eval contexts.
Every time you call a function, your engine will spawn it in it's own function context. Also, there is a such called Activation object created. This mystic object is part of a function context which consists out of at least:
[[Scope chain]]
Activation object
"this" context value
There may be more properties on different engines, but these three are required for any implementation of ES. However, back to the topic. If a function context is invoked, all parent contexts (or more precisly, the Activation objects from the parent contexts) are copied over into the [[Scope]] property. You can think of this property like an array, which holds (Activation-) Objects. Now, any function related information is stored in the Activation object (formal parameters, variables, function declarations).
In your example, the digits variable is stored in the Activation object for namenew. The second when the inner anonymous function is created, it adds that Activation object into its [[Scope]] propertys. When you call digits[n] there, Javascript first tries to find that variable in its own Activation object. If that fails, the search goes into the Scopechain. And voila, there we found the variable because we copied the AO from the outer function.
I already wrote too much for a short answer, but to really give a good answer to such a question you have to explain some basic knowledge about ES here. I guess that is just enough to give you an idea what really happens "under the hood" (there is a lot more to know, if you want to read more I'll give you some references).
You asked for it, you get it:
http://dmitrysoshnikov.com/ecmascript/javascript-the-core/
The first function recreates digits every time it's executed. If it's a large array this is needlessly expensive.
The second function stores digits in a context shared only with namenew. Every time namenew is executed it only performs a single operation: return digits[n].
An example like this wont show any noticeable gains in performance, but with very large arrays/objects/function calls performance will be improved significantly.
In an OOP perspective using a closure in this manner is similar to storing data in a static variable.
Don't forget that namenew is receiving the result of the closure function. The closure itself is only executed once.