Proper way to handle scope in JavaScript - javascript

I have code that schematically follows the pattern below. The significant part is that there's a parameter declared in the outer function that is later used in the inner one.
function outer(){
var parameter = 3;
this.value = parameter;
$("#something").on("click", function(target){
target.value = parameter / 2;
});
}
In reality, the inner functions are quite a few and rather lengthy so I was hoping to move them out in order to improve readability, like so.
var parameter = 3;
function outer(){
this.value = parameter;
$("#something").on("click", inner);
}
function inner(target){
target.value = parameter / 2;
}
However, what I noticed is that, because of the scoping paradigm of JavaScript, I had to move out the parameter declaration out of the outer function, hence making it global, which to me seems like a disadvantage. (In reality, there are many parameters being used so passing them directly defeats the purpose.)
I can't decide which approach is less flawed. The question is if it's OK to pollute the global scope in order to gain readability or if it's an absolute no-no.

Re your revised question:
The question is if it's OK to pollute the global scope in order to gain readability or if it's an absolute no-no.
It's an absolute no-no. The global namespace is already far, far too polluted. And there's almost never any reason to do it: Instead, you can pollute use a scope that contains all of your code (near-global, if you will) as much as you want:
(function() {
// Our private scope
var lots, of, vars, here;
function outer() {
// ...
}
function inner() {
// ...
}
})();
That at least keeps your variables from truly being globals.
It's still best, though, to keep the scope of variables as constrained as possible. The cool thing is you can repeat the above as necessary to create mini-scopes for common code, nesting them like matryoshka.
Earlier answer before the question revision:
If the question is "what's better," the answer is: Neither. They each have their place, they're useful for different things.
If you're looking for a third solution, you can use partial application (sometimes called currying, though purists have an issue with that). JavaScript doesn't have a built-in partial application feature that doesn't mess with this, but you can easily add one:
(function() {
// Note use of micro-scope here. It's a micro-optimiziation to avoid
// looping up `slice` every time we need it. Mostly it's a justification
// for demonstrating a micro-scope. :-)
var slice = Array.prototype.slice;
Object.defineProperty(Function.prototype, "curry", { // purists: sorry ;-)
value: function() {
var f = this;
var args = slice.call(arguments, 0);
return function() {
return f.apply(this, args.concat(slice.call(arguments)));
};
}
});
})();
Then
function outer(){
var parameter = 3;
this.value = parameter;
$("#something").on("click", inner.curry(parameter));
}
function inner(parameter, target){
target.value = parameter / 2;
}
You've mentioned that there may be a lot of these; if so, you might consider an object with properties instead, so you just curry the object reference rather than a lot of discrete variables.
Example:
(function() {
// Note use of micro-scope here. It's a micro-optimiziation to avoid
// looping up `slice` every time we need it. Mostly it's a justification
// for demonstrating a micro-scope. :-)
var slice = Array.prototype.slice;
Object.defineProperty(Function.prototype, "curry", { // purists: sorry ;-)
value: function() {
var f = this;
var args = slice.call(arguments, 0);
return function() {
return f.apply(this, args.concat(slice.call(arguments)));
};
}
});
})();
function outer() {
var parameter = 3;
setTimeout(inner.curry(parameter));
}
function inner(parameter) {
console.log("Got parameter = " + parameter);
}
outer();

Related

How can I get rid of the `this` keyword in local functions?

I'm writing a small JavaScript game framework and often use objects' properties, like
this.depth = this.y;
But these this'es are quite annoying #_#. Is there a way to write just…
depth = y;
…not affecting global object?
My instances are created via two factory functions, and they make a limited list of predefined variables, so all of them have depth, y, etc. Functions are applied to instances by .apply() method, though it all may be changed.
The reason I need to omit this keyword is that the framework is designed not for me only, but for other people too. I don't need to remove this in the framework itself, but the this keyword harvests much time while coding applications based on this library. The only solution I know so far is making 'private' variables, but it makes some inconvenience for people who haven't worked with JavaScript before, and manipulating obj1 from obj2 causes making lots of anonymous functions with .apply – even more hell. So, as I can see, there is no panacea in JavaScript.
Constructors:
/*...*/
'Copy' : function (type) {
var obj = {
'x':0,
'y':0,
'xprev':0,
'yprev':0,
/*...*/
};
return obj;
},
'make' : function (type,x,y) {
obj = ct.types.Copy(type);
obj.x = obj.xprev = obj.xstart = x;
obj.y = obj.yprev = obj.ystart = y;
/*...*/
ct.stack.push(obj);
}
/*...*/
Your question is hard to answer without seeing any code, but in general, "modern" JavaScript OOP based on factories and closures is less verbose and more idiomatic than the old "wannabe Java" style with new's and this'es.
Old style:
function Something() {
this.depth = 0;
}
Something.prototype.incDepth = function() {
this.depth++;
}
foo = new Something()
New style:
function Something() {
var depth = 0;
return {
incDepth: function() {
depth++;
}
}
}
foo = Something()
I agree that the this keyword is not just annoying but also does not make much sense IMHO (at least the way it is implemented), as it encourages people to use global variables over properties.
IMHO it shouldn't be needed to access the properties of an object inside that object. (only if it needs to be distinguished from a parameter i.e.)
On the other hand global variables could use a keyword, like globals.something
Sadly don't know a real solution, only to create a shortcut, like:
const t = this;
t.depth = t.y;
But I fear t will then be global too … :(
PS: So maybe better to have t as variable and at the beginning of each function write: t = this;
So you could have something similar to:
GameObject = {
x: 5,
y: 10,
action: function() {
t = this;
t.depth = t.y;
...
}
...
}

How does defining and immediately calling an anonymous function solve namespace problems?

I'm reading this page where it says:
myNameSpace = function(){
var current = null;
function init(){...}
function change(){...}
function verify(){...}
return{
init:init,
change:change
}
}();
Instead of returning the properties and methods I just return pointers
to them. This makes it easy to call functions and access variables
from other places without having to go through the myNameSpace name.
But I don't see how that's true. You still have to do myNameSpace.init() to call init. init() alone doesn't work.
Edit: it occurred to me later that maybe the author meant they were able to call init() without qualification inside the anonymous function. But what stumped me is that the author's previous examples were already able to do that. Specifically, in the immediately foregoing example:
myNameSpace = function(){
var current = null;
function verify(){...}
return{
init:function(){...}
change:function(){...}
}
}();
s/he defined init as s/he was returning it, instead of the example above where s/he defined init first then returned a pointer to it. But in that earlier example, within the anonymous function, if you wanted to call init() without having to do myNameSpace.init(), you already can. So how is the quoted example better?.
Can someone explain? Thanks.
The idea of using a function to clean up scope is, let's say you have a program that looks like this:
var number = 10;
var multiplier = 2;
var endingText = " days left!";
var string = (10 * 2) + endingText;
// string is "20 days left!"
This is an extremely contrived example, but hopefully it's obvious enough that this will declare four variables in the global scope, which is horrible. Let's say what you really want is string, but you still want to keep the other three variables around for whatever reason. You can put them inside an anonymous function, like so:
var string;
(function(){
var number = 10;
var multiplier = 2;
var endingText = " days left!";
string = (10 * 2) + endingText;
})();
// string is still "20 days left!"
Because variables are function scoped, number, multiplier and endingText are NOT declared in the global scope. However, you are still able to use them to get the result that you wanted in the first place.
By the way, you need to wrap parens around a function if you want to immediately invoke it. Also, you should not confuse this with namespacing. Namespacing in JavaScript is the idea of assigning meaningful values to the properties of objects.
var foo = {
hello: "goodbye",
frank: "bob"
};
hello and frank are declared in the foo namespace. That's all there is to it. The example that you posted uses both the namespacing concept and immediately invoking function concept to clean up variables.
The wording is a bit confusing. He meant to say:
Functions and variables can now be easily accessed without a namespace from inside the module
- in contrast to the object literal pattern or the previous example where he put the public methods directly on the exported object. Of course, from outside you always will need to access them as properties of the namespace object - that's the whole point of making it a namespace :-)
For an example, let's fill the functions with a some minimal code:
myNameSpace = function(){
var current = null;
function verify(…){…}
return {
init:function(el){
el.addEventListener("input", myNameSpace.change, false);
// ^^^^^^^^^^^^^^^^^^
},
change:function(){
if (!verify(this.value)) alert("wrong");
}
}
}();
myNameSpace.init(document.getElementById("testInput"));
vs
myNameSpace = function(){
var current = null;
function verify(…){…}
function change(){
if (!verify(this.value)) alert("wrong");
}
function init(el){
el.addEventListener("input", change, false);
// ^^^^^^
}
return {
init:init,
change:change
}
}();
myNameSpace.init(document.getElementById("testInput")); // no difference here
The differences may be minimal in this example, but when you have lots of functions mutually referencing each other it can matter. Also, you would know that all local, namespace-less functions belong to the current module, which massively increases maintainability when dealing with many different namespaces.

How to organise my code in 'modules'?

I'm trying to wrap my head around organising my code. I have several modules within my project, which I'd like to organise.
The point is that all what has come to my mind doesn't work out. I'm currently thinking of four ideas:
Simple object - Is not useful due to scoping issues. Using this.a would work, but this has a different meaning depending on who called it so it's not reliable. For example, I once assigned a function to a WebSocket class, but all of a sudden this referred to the WebSocket instance when the function was called by a WebSocket event. I could use bind(foo) each time I call the function, but there must be another way I guess.
var foo = {
a: 3,
s: function() {
alert(a); // a doesn't exist in this scope
alert(this.a); // 'this' isn't always foo
alert(foo.a); // I would have to put 'foo.' before each variable
// reference, but I'm sure that's not the way to do it
}
};
Instance - a is not defined. Again, this isn't reliable.
var foo = function() {
this.a = 3;
this.s = function() {
alert(a);
};
};
var foo_instance = new foo();
foo_instance.a = 4;
foo_instance.s(); // Error: a is not defined
Closure with instance - Doesn't return anything; it stays undefined.
var foo = (function() {
this.a = 3;
this.s = function() {
alert(a);
};
})();
// foo === undefined
Closure with getter/setter - Works beautifully on Chrome, however IE doesn't support getters/setters.
var foo = (function() {
var a = 3;
return {
get a() { return a; },
set a(v) { a = v; },
s: function() {
alert(a); // Doesn't work in IE as getters/setters are
// not supported
}
};
})();
How would I effectively organise my modules, so that I can access the properties safely and in a cross-browser way?
Thanks.
3 is undefined because you are not returning anything. instead of assigning properties and methods to 'this', try this:
var foo = (function() {
var self = {};
self.someProperty = someValue;
self.someFunction = function () {
}
return self;
}());
foo will now return an object with the properties and methods defined. doing it this way you never have to wonder what 'this' is actually referring to.
It seems to me that you have no real understand of how this and closures work in JavaScript.
Please read up on both of these topics and also have a look at namespaces.
There are a ton of different ways how one could realize modules, but it doesn't make much sense to talk about it here unless you understand the basics, so please refer to my links for a in-depth explanation.
Your first code snippet uses a closure, and corresponds to a pattern that was made popular by the yui library. The second pattern corresponds to the notion of private, public and privileged members of an object.
I recommend that you read this staple article about javascript private members by Douglas Crockford, and go either with the first option or the second. They are semantically equivalent.
(The third and the forth snippets seem overly complex to me in comparison to the first two)

I know what a closure is, but I still dont understand why (or when) you would use them

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.

What are the use cases for closures/callback functions in JavaScript?

I was listening to Crockford's talk on JavaScript closures and am convinced of the benefit of information hiding, but I do not have a firm understanding of when to use callback functions.
It is mostly a true statement that a person could accomplish the same functionality with or without callbacks.
As someone who is writing code, what heuristics or cues should I keep in mind when determining when to use callbacks/closures?
I am not looking for the blanket statement 'Closures make more secure code', rather a list of practical examples or rules of thumb for when callbacks are the right idea.
Crockford's Presentation:
http://www.yuiblog.com/blog/2010/04/08/video-crockonjs-5/
Firstly:
Callback: A function passed as an argument to another function, usually to be called as a result of an event occurring.
Closure: A retained scope. I.e. the concept that when you declare a function within another function, the outer function's scope is accessible within the inner function.
Callbacks can also be closures but are not always.
This is a callback:
someProcess(myCallback);
function myCallback() {
alert('Done...');
}
function someProcess(callback) {
// does stuff...
// ...
callback();
}
A closure:
function foo(msg) {
function bar() {
// I can access foo's scope
// (i.e. bar can access everything that foo can access)
alert(msg);
}
return bar;
}
foo('hello')(); // alerts "hello"
One common usage of closures is to provide information-hiding, which is helpful in bringing some kind of encapsulation to the language. Have a look at the module pattern to see this in action.
Another common usage is when the binding event handlers to elements. E.g.
var myElements = [ /* DOM Collection */ ];
for (var i = 0; i < 100; ++i) {
myElements[i].onclick = function() {
alert( 'You clicked on: ' + i );
};
}
That wouldn't work. By the time the element is clicked, the variable i is 99. To make this work properly we could use a closure to capture the value of i:
function getHandler(n) {
return function() {
alert( 'You clicked on: ' + n );
};
}
for (var i = 0; i < 100; ++i) {
myElements[i].onclick = getHandler(i);
}
Let's say you want a function that you can use to return a unique "id" value to use when you create new DOM elements. Now, in something like Java, you could create a class with an internal private counter, and then have a method that appends the counter to some prefix string. Well, in Javascript:
var getId = (function() {
var counter = 0;
return function() {
return "prefix" + counter++;
};
})();
Now the variable "getId" is bound to a function that's created by another function, and created in such a way that it has a persistent variable to use between invocations. Similarly, if I wanted to have a family of "getId" functions (say, one for each type of DOM element I might add), I could do this:
var getIdFunc = function(prefix) {
var counter = 0;
return function() {
return prefix + counter++;
};
};
var getId = {
'div': getIdFunc('div'),
'span': getIdFunc('span'),
'dl': getIdFunc('dl'),
// ...
};
Now I can call getId.div() to get a new "id" value for a new <div>. The function was created by calling a function that provides two values stashed away in a closure: the prefix string (passed in as an argument) and the counter (a var declared in the closure scope).
Once you get used to it, the facility is so flexible and useful that you'll feel pain at moving back to an environment without it.
Oh, and here's a tip to help keep you off StackOverflow should you try this out: it's an issue that pops up all the time:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = function() {
alert("hello from element " + i);
};
}
What's the problem here? Well, that "i" variable that's referenced by that function is the "i" from the scope in which that loop runs. That variable, you'll note, gets incremented through the loop (duhh, right?). Well, every single one of those little functions created and assigned as event handlers will share that same, single variable "i" in the closure scope. Oops! The solution is to do something like this:
for (var i = 0; i < 10; ++i) {
var id = "foo" + i;
var element = document.getElementById(id);
element.onclick = (function(iCopy) {
return function() {
alert("hello from element " + iCopy);
};
})(i);
}
We make a copy of the outer "i" into a closure scope of its own, so now each event handler has its own!
To summarize: the technique of leveraging closures comes up all the freaking time once you get used to it. It's not a free ticket into a new wonderland of error-free programming; don't get me wrong. It is, however, a very useful and flexible paradigm.
This writeup from Mozilla may answer why use closures and when
Also, see this set of examples (especially "What can be done with Closures?" section that has the following exmples):
Example 1: setTimeout with Function References
Example 2: Associating Functions with Object Instance Methods
Example 3: Encapsulating Related Functionality
I have e feeling that this can be traced to Crockford, but the classic use of closures is to emulate private instance or static variables (which JavaScipt lacks)

Categories