In one of his videos (at around 1 min 25 seconds. The clock in the video goes backwards, so it's at -27:45), Douglas Crockford mentions that Javascript closures are a source of enormous expressive power and unlike other power constructs are also secure. He specifically mentions that in Javascript closures constraint scope, which makes them more secure.
Can someone help me with a few examples which show how scoping rules of Javascript closures make them more secure than other languages which have closures. Also are there any other things which make Javascript closures more secure than their counterparts in other languages?
They are "secure" in the sense that only code within the lexical scope of the closure can directly access the variables of the closures function-scope. I recommend reading the Jibbering Closure Notes, in general.
Any "leaked" object may still introduce an data-manipulation/side-effect point. The closures in ECMAScript are no more "secure" than in any other language with similar closure semantics -- in this sense "secure" means "private variable access". On the other hand, some languages already have more controlled visibility modifiers of members (e.g. Java or C# with private/public distinctions).
This is, of course, if one considers JavaScript objects which "merely" rely on prototypes to be "insecure". (If someone uses my code incorrectly, let them -- and if it it breaks, let them burn ;-)
Personally I find Mr. Crockford a fine evangelist -- but not for my religion ;-) One can say all sorts of good thing about X without properly analyzing it in relationship to Y.
Closures give you the ability to encapsulate (hide) data, as desirable with object oriented design.
The ability to effectively define "private" variables and publish a "public" interface makes it less likely that a programmer will misuse the object - i.e. mess with the data value directly and yield unexpected side-effects.
// returns an object that does not itself possess "var a"
// The closure gives indirect access to a, via the public getter and setter.
function f() {
var a = 1;
return {
getA: function() {
return a;
},
setA: function( A ) {
a = A;
}
};
}
var MyObj = new f();
alert(MyObj.a); // --> undefined
alert(MyObj.getA()); // --> 1
MyObj.setA(5);
alert(MyObj.getA()); // --> 5
EXAMPLE
Related
I have used JS for two years and my pluralsight accessment rates me as proficient in JS, I understand prototypical inheritance, higher order functions, IIFEs etc and I have used them in real world instances but closures is one of those concept that you understand but can't find any reason why you would want to use them in real world development, I mean I know that if I say,
function expClosure(val){
//do something to val-->anotherVal
return function(val){return anotherVal)};
}
var exp = expClosure(val);
exp(); --> returns the value of anotherVal;
My question is why would I want to do this, or rather what specific instances can lead me to consider using this.
The main benefit to closures is you can "partially apply" a function using a closure, then pass the partially applied function around, instead of needing to pass the non-applied function, and any data you'll need to call it (very useful, in many scenarios).
Say you have a function f that will need in the future 2 pieces of data to operate. One approach is you could pass both pieces in as arguments when you call it. The problem with this approach is if the first piece of data is available immediately, and the second isn't, you'll have to pass it around with f so it's in scope when you want to call the function.
The other option is to give the available data to the function immediately. You can create a closure over the data, have the function reference the external data, then pass the function around by itself.
Option 2 is much simpler.
You can also use closures to implement static variables in functions in languages that don't natively support them. Clojure (the language) implements it's memoize function by having it return a modified version of the passed function that holds a reference to a map representing argument/return value pairs. Before the function is run, it first checks if the arguments already exist in the map. If they do, it returns the cached return value instead of recalculating it.
(Adapted from my answer to another question)
I wrote a bit about this in my practical bachelor thesis(2.2.2)
Hiding variables is a valuable usage of closure. Compared to some other languages variables can't be declared as private, public, etc. in JavaScript, but using closure you can hide variables that can only be used internally. E.g.
function Car() {
var speed = 0;
return {
accelerate: function() {
speed++;
}
}
}
var car = new Car();
car.accelerate();
speed is accessible by accelerate due to closure, but is otherwise completely inaccessible.
Since this question doesn't demand a programmatic answer, I am adding an answer and not a comment.
The example you quoted in the question is, I agree of a closure, and I am sure having access to pluralsight lectures, you well understand closures. So the aforestated example is not the only use case of closures. The closures are the functions which remember the scope in which they were created.
An obvious example of this is a callback registering mechanism which every one uses in jQuery. There are closures everywhere, and many of us have been unknowingly writing closures.
So if you have used redux, you would know the entire concept is based on closure, i.e. encapsulating the data(called state of application). Closure provisions a concept of private variables used in OOPS supporting languages.
I am adding another example of closure below, so you might be able to relate.
function processOrder(amount){
var temp_order_id = +new Date() + 'USERID';
var afterPaymentCompleteOrder = function(status){//callback
//afterPaymentCompleteOrder is a closure as it remembers the scope in which it is created when it is being called. So when ivoked it remembers the value of temp_order_id
if(status){
complete_order_method(temp_order_id);
}
else
delete_order_details(temp_order_id);
}
start_payment_process(amount, afterPaymentCompleteOrder);
}
I've read many questions on closures and JavaScript on SO, but I can't find information about what happens to a function when it gets closured in. Usually the examples are string literals or simple objects. See the example below. When you closure in a function, the original function is preserved even if you change it later on.
What technically happens to the function preserved in a closure? How is it stored in memory? How is it preserved?
See the following code as an example:
var makeFunc = function () {
var fn = document.getElementById; //Preserving this, I will change it later
function getOriginal() {
return fn; //Closure it in
}
return getOriginal;
};
var myFunc = makeFunc();
var oldGetElementById = myFunc(); //Get my preserved function
document.getElementById = function () { //Change the original function
return "foo"
};
console.log(oldGetElementById.call(document, "myDiv")); //Calls the original!
console.log(document.getElementById("myDiv")); //Returns "foo"
Thanks for the comments and discussion. After your recommendations, I found the following.
What technically happens to the function preserved in a closure?
Functions as objects are treated no differently than any other simple object as closured variables (such as a string or object).
How is it stored in memory? How is it preserved?
To answer this, I had to dig through some texts on programming languages. John C. Mitchell's Concepts in Programming Languages explains that closured variables usually end up in the program heap.
Therefore, the variables defined in nesting subprograms may need lifetimes that are of the entire program, rather than just the time during which the subprogram in which they were defined is active. A variable whose lifetime is that of the whole program is said to have unlimited extent. This usually means they must be heap-dynamic, rather than stack-dynamic.
And more specific to JavaScript runtimes, Dmitry Soshnikov describes
As to implementations, for storing local variables after the context is destroyed, the stack-based implementation is not fit any more (because it contradicts the definition of stack-based structure). Therefore in this case closured data of the parent context are saved in the dynamic memory allocation (in the “heap”, i.e. heap-based implementations), with using a garbage collector (GC) and references counting. Such systems are less effective by speed than stack-based systems. However, implementations may always optimize it: at parsing stage to find out, whether free variables are used in function, and depending on this decide — to place the data in the stack or in the “heap”.
Further, Dmitry shows a varied implementation of the parent scope in function closures:
As we mentioned, for optimization purpose, when a function does not use free variables, implementations may not to save a parent scope chain. However, in ECMA-262-3 specification nothing is said about it; therefore, formally (and by the technical algorithm) — all functions save scope chain in the [[Scope]] property at creation moment.
Some implementations allow access to the closured scope directly. For example in Rhino, the [[Scope]] property of a function corresponds to a non-standard property __parent__.
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!
http://a2.twimg.com/a/1302724321/javascripts/widgets/widget.js?1302801865
It is setup like this at a high level:
public namespace:
TWTR = window.TWTR || {};
Then a closure:
(function() {
...
})(); // #end application closure
Within the application closure:
TWTR.Widget = function(opts) {
this.init(opts);
};
(function() {
// Internal Namespace.
var twttr = {};
})();
Some methods are marked public, others private, and the only difference seems to be the naming convention (private starts with underscore '_').
Is it designed using the module pattern?
Why or what benefit do you get with a closure within a closure?
Since they load the widget.js before jquery, this means widget is designed to run w/o jquery since order matters correct?
Just trying to learn from this thing!
It is setup like this at a high level:
public namespace:
TWTR = window.TWTR || {};
That is bad coding practice, variables should always be declared with var. And there are no "namespaces" in javascript, that term is applied to the above construct but it isn't really appropriate. Better to say its methods are contained by an object.
Then a closure:
> (function() { ...
>
> })(); // #end application closure
That pattern has come to be called an immediately invoked function expression or iife. Not sure I like the name, but there you go. Anyway, it doesn't necessarily create any useful closures. A closure is only useful if a function creates variables that become bound to some other execution context that survives beyond the life of the function that created them (I hope that doesn't read like gobbledy-goop). You don't need an iife to create a closure.
However, you can use the above pattern to create closures since it's a function much like any other function.
Within the application closure:
> TWTR.Widget = function(opts) {
> this.init(opts); }; (function() {
> // Internal Namespace.
> var twttr = {}; })();
Some methods are marked public, others
private, and the only difference seems
to be the naming convention (private
starts with underscore '_').
The use of "public" and "private" are a bit misleading in javascript. The use of underscore to start identifer names indicates something that should only be used within the current scope, or by the "library" code itself. It's a bit redundant since the code should have a published API and any method that isn't part of the API shouldn't be avaialble externally.
But that is largely a matter of coding style and personal preference.
Is it designed using the module pattern?
Richard Cornford's "module pattern" is just that, a pattern. It's handy for simulating "private" variables in javascript, and also to share properties between functions or methods other than by the usual prototype inheritance. widget.js might be implemented (in parts) using the module pattern, but it it was likely designed by considering requirements and functionality. ;-)
Why or what benefit do you get with a closure within a closure?
Exactly the same benefits of any closure as stated above. Accessing variables essentially by placing them on an appropriate part of the scope chain is essentially the same as accessing properties via a [[prototype]] chain, only with (very different) mechanics - one uses identifier resolution on the scope chain, the other property resolution on the [[prototype]] chain.
Edit
One drawback is that the entire activation object that the closed variable belongs to is probably retained in memory, so if you just need access to a shared variable, better to consider some other scheme, perhaps even classic prototype inheritance. Or at least if you are going to use closures, try to keep the related activation object as small as reasonably possible (e.g. set any variables that aren't used to null just before exiting).
e.g.
var foo = (function() {
// Variables available for closure
var a, b, c;
// Use a, b, c for stuff
...
// Only want closure to c
a = null;
b = null;
return function() {
// use c
}
}());
Since they load the widget.js before jquery, this means widget is designed to run w/o jquery since order matters correct?
I can't access the linked resource right now (corporate blocking of twitter domain), but the load order suggests you are correct. However, some code execution might be delayed until the document is fully loaded so it isn't a guaranteee, you'll need to look at the code.
I'm thinking that stuff like with(Math){document.body.innerHTML= PI} wouldn't exactly be good practise.
I would call it bad practice, considering how it affects the scope chain.
Take a look at this article from Douglas Crockford: "with Statement Considered Harmful"
The short summary of the link in Matt's answer is that the problem with using the "with" statement is that the variables within the "with"'s block are ambiguous. Using the following example:
with(foo.doo.diddly.doo){
bar = 1;
baz = 1;
}
If you're not absolutely certain that foo.doo.diddly.doo has the bar or baz properties, you don't know if the bar and baz within the with statement are getting executed, or some global bar and baz. It's better to use variables:
var obj = foo.doo.diddly.doo;
obj.bar = 1;
obj.baz = 1;
In your example, though, Math is hardly a long enough term to justify even using a variable, but I'm guessing you have a more verbose application in mind than you've used for the question.
If you access (nested) object properties once, then there is no need "cache" them.
But if you access them more then once, then you should store a reference in a local variable. This has two advantages:
(nested) properties don't need to be lookup up more then once (potentially in the inheritance chain which is slow!).
Especially global objects (but any object that is not in the current scope) only needs to be looked up once in the scope chain. Subsequent access will be faster.
And now the connection to with:
It generates a new scope at beginning of the current scope chain. That means that any access to other variables/objects will cost at least one scope lookup more, even to variables that are local to the function.