Related
I'm trying my hardest to wrap my head around JavaScript closures.
I get that by returning an inner function, it will have access to any variable defined in its immediate parent.
Where would this be useful to me? Perhaps I haven't quite got my head around it yet. Most of the examples I have seen online don't provide any real world code, just vague examples.
Can someone show me a real world use of a closure?
Is this one, for example?
var warnUser = function (msg) {
var calledCount = 0;
return function() {
calledCount++;
alert(msg + '\nYou have been warned ' + calledCount + ' times.');
};
};
var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();
Suppose, you want to count the number of times user clicked a button on a webpage.
For this, you are triggering a function on onclick event of button to update the count of the variable
<button onclick="updateClickCount()">click me</button>
Now there could be many approaches like:
You could use a global variable, and a function to increase the counter:
var counter = 0;
function updateClickCount() {
++counter;
// Do something with counter
}
But, the pitfall is that any script on the page can change the counter, without calling updateClickCount().
Now, you might be thinking of declaring the variable inside the function:
function updateClickCount() {
var counter = 0;
++counter;
// Do something with counter
}
But, hey! Every time updateClickCount() function is called, the counter is set to 1 again.
Thinking about nested functions?
Nested functions have access to the scope "above" them.
In this example, the inner function updateClickCount() has access to the counter variable in the parent function countWrapper():
function countWrapper() {
var counter = 0;
function updateClickCount() {
++counter;
// Do something with counter
}
updateClickCount();
return counter;
}
This could have solved the counter dilemma, if you could reach the updateClickCount() function from the outside and you also need to find a way to execute counter = 0 only once not everytime.
Closure to the rescue! (self-invoking function):
var updateClickCount = (function(){
var counter = 0;
return function(){
++counter;
// Do something with counter
}
})();
The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.
This way updateClickCount becomes a function. The "wonderful" part is that it can access the counter in the parent scope.
This is called a JavaScript closure. It makes it possible for a function to have "private" variables.
The counter is protected by the scope of the anonymous function, and can only be changed using the updateClickCount() function!
A more lively example on closures
<script>
var updateClickCount = (function(){
var counter = 0;
return function(){
++counter;
document.getElementById("spnCount").innerHTML = counter;
}
})();
</script>
<html>
<button onclick="updateClickCount()">click me</button>
<div> you've clicked
<span id="spnCount"> 0 </span> times!
</div>
</html>
Reference: JavaScript Closures
I've used closures to do things like:
a = (function () {
var privatefunction = function () {
alert('hello');
}
return {
publicfunction : function () {
privatefunction();
}
}
})();
As you can see there, a is now an object, with a method publicfunction ( a.publicfunction() ) which calls privatefunction, which only exists inside the closure. You can not call privatefunction directly (i.e. a.privatefunction() ), just publicfunction().
It's a minimal example, but maybe you can see uses to it? We used this to enforce public/private methods.
The example you give is an excellent one. Closures are an abstraction mechanism that allow you to separate concerns very cleanly. Your example is a case of separating instrumentation (counting calls) from semantics (an error-reporting API). Other uses include:
Passing parameterised behaviour into an algorithm (classic higher-order programming):
function proximity_sort(arr, midpoint) {
arr.sort(function(a, b) { a -= midpoint; b -= midpoint; return a*a - b*b; });
}
Simulating object oriented programming:
function counter() {
var a = 0;
return {
inc: function() { ++a; },
dec: function() { --a; },
get: function() { return a; },
reset: function() { a = 0; }
}
}
Implementing exotic flow control, such as jQuery's Event handling and AJAX APIs.
JavaScript closures can be used to implement throttle and debounce functionality in your application.
Throttling
Throttling puts a limit on as a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."
Code:
const throttle = (func, limit) => {
let isThrottling
return function() {
const args = arguments
const context = this
if (!isThrottling) {
func.apply(context, args)
isThrottling = true
setTimeout(() => isThrottling = false, limit)
}
}
}
Debouncing
Debouncing puts a limit on a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
Code:
const debounce = (func, delay) => {
let debouncing
return function() {
const context = this
const args = arguments
clearTimeout(debouncing)
debouncing = setTimeout(() => func.apply(context, args), delay)
}
}
As you can see closures helped in implementing two beautiful features which every web application should have to provide smooth UI experience functionality.
Yes, that is a good example of a useful closure. The call to warnUser creates the calledCount variable in its scope and returns an anonymous function which is stored in the warnForTamper variable. Because there is still a closure making use of the calledCount variable, it isn't deleted upon the function's exit, so each call to the warnForTamper() will increase the scoped variable and alert the value.
The most common issue I see on Stack Overflow is where someone wants to "delay" use of a variable that is increased upon each loop, but because the variable is scoped then each reference to the variable would be after the loop has ended, resulting in the end state of the variable:
for (var i = 0; i < someVar.length; i++)
window.setTimeout(function () {
alert("Value of i was "+i+" when this timer was set" )
}, 10000);
This would result in every alert showing the same value of i, the value it was increased to when the loop ended. The solution is to create a new closure, a separate scope for the variable. This can be done using an instantly executed anonymous function, which receives the variable and stores its state as an argument:
for (var i = 0; i < someVar.length; i++)
(function (i) {
window.setTimeout(function () {
alert("Value of i was " + i + " when this timer was set")
}, 10000);
})(i);
In the JavaScript (or any ECMAScript) language, in particular, closures are useful in hiding the implementation of functionality while still revealing the interface.
For example, imagine you are writing a class of date utility methods and you want to allow users to look up weekday names by index, but you don't want them to be able to modify the array of names you use under the hood.
var dateUtil = {
weekdayShort: (function() {
var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
return function(x) {
if ((x != parseInt(x)) || (x < 1) || (x > 7)) {
throw new Error("invalid weekday number");
}
return days[x - 1];
};
}())
};
Note that the days array could simply be stored as a property of the dateUtil object, but then it would be visible to users of the script and they could even change it if they wanted, without even needing your source code. However, since it's enclosed by the anonymous function which returns the date lookup function it is only accessible by the lookup function so it is now tamperproof.
There is a section on Practical Closures at the Mozilla Developer Network.
If you're comfortable with the concept of instantiating a class in the object-oriented sense (i.e. to create an object of that class) then you're close to understanding closures.
Think of it this way: when you instantiate two Person objects you know that the class member variable "Name" is not shared between instances; each object has its own 'copy'. Similarly, when you create a closure, the free variable ('calledCount' in your example above) is bound to the 'instance' of the function.
I think your conceptual leap is slightly hampered by the fact that every function/closure returned by the warnUser function (aside: that's a higher-order function) closure binds 'calledCount' with the same initial value (0), whereas often when creating closures it is more useful to pass different initializers into the higher-order function, much like passing different values to the constructor of a class.
So, suppose when 'calledCount' reaches a certain value you want to end the user's session; you might want different values for that depending on whether the request comes in from the local network or the big bad internet (yes, it's a contrived example). To achieve this, you could pass different initial values for calledCount into warnUser (i.e. -3, or 0?).
Part of the problem with the literature is the nomenclature used to describe them ("lexical scope", "free variables"). Don't let it fool you, closures are more simple than would appear... prima facie ;-)
Here, I have a greeting that I want to say several times. If I create a closure, I can simply call that function to record the greeting. If I don't create the closure, I have to pass my name in every single time.
Without a closure (https://jsfiddle.net/lukeschlangen/pw61qrow/3/):
function greeting(firstName, lastName) {
var message = "Hello " + firstName + " " + lastName + "!";
console.log(message);
}
greeting("Billy", "Bob");
greeting("Billy", "Bob");
greeting("Billy", "Bob");
greeting("Luke", "Schlangen");
greeting("Luke", "Schlangen");
greeting("Luke", "Schlangen");
With a closure (https://jsfiddle.net/lukeschlangen/Lb5cfve9/3/):
function greeting(firstName, lastName) {
var message = "Hello " + firstName + " " + lastName + "!";
return function() {
console.log(message);
}
}
var greetingBilly = greeting("Billy", "Bob");
var greetingLuke = greeting("Luke", "Schlangen");
greetingBilly();
greetingBilly();
greetingBilly();
greetingLuke();
greetingLuke();
greetingLuke();
Another common use for closures is to bind this in a method to a specific object, allowing it to be called elsewhere (such as as an event handler).
function bind(obj, method) {
if (typeof method == 'string') {
method = obj[method];
}
return function () {
method.apply(obj, arguments);
}
}
...
document.body.addEventListener('mousemove', bind(watcher, 'follow'), true);
Whenever a mousemove event fires, watcher.follow(evt) is called.
Closures are also an essential part of higher-order functions, allowing the very common pattern of rewriting multiple similar functions as a single higher order function by parameterizing the dissimilar portions. As an abstract example,
foo_a = function (...) {A a B}
foo_b = function (...) {A b B}
foo_c = function (...) {A c B}
becomes
fooer = function (x) {
return function (...) {A x B}
}
where A and B aren't syntactical units but source code strings (not string literals).
See "Streamlining my javascript with a function" for a concrete example.
Here I have one simple example of the closure concept which we can use for in our E-commerce site or many others as well.
I am adding my JSFiddle link with the example. It contains a small product list of three items and one cart counter.
JSFiddle
// Counter closure implemented function;
var CartCouter = function(){
var counter = 0;
function changeCounter(val){
counter += val
}
return {
increment: function(){
changeCounter(1);
},
decrement: function(){
changeCounter(-1);
},
value: function(){
return counter;
}
}
}
var cartCount = CartCouter();
function updateCart() {
document.getElementById('cartcount').innerHTML = cartCount.value();
}
var productlist = document.getElementsByClassName('item');
for(var i = 0; i< productlist.length; i++){
productlist[i].addEventListener('click', function(){
if(this.className.indexOf('selected') < 0){
this.className += " selected";
cartCount.increment();
updateCart();
}
else{
this.className = this.className.replace("selected", "");
cartCount.decrement();
updateCart();
}
})
}
.productslist{
padding: 10px;
}
ul li{
display: inline-block;
padding: 5px;
border: 1px solid #DDD;
text-align: center;
width: 25%;
cursor: pointer;
}
.selected{
background-color: #7CFEF0;
color: #333;
}
.cartdiv{
position: relative;
float: right;
padding: 5px;
box-sizing: border-box;
border: 1px solid #F1F1F1;
}
<div>
<h3>
Practical use of a JavaScript closure concept/private variable.
</h3>
<div class="cartdiv">
<span id="cartcount">0</span>
</div>
<div class="productslist">
<ul>
<li class="item">Product 1</li>
<li class="item">Product 2</li>
<li class="item">Product 3</li>
</ul>
</div>
</div>
Use of Closures:
Closures are one of the most powerful features of JavaScript. JavaScript allows for the nesting of functions and grants the inner function full access to all the variables and functions defined inside the outer function (and all other variables and functions that the outer function has access to). However, the outer function does not have access to the variables and functions defined inside the inner function.
This provides a sort of security for the variables of the inner function. Also, since the inner function has access to the scope of the outer function, the variables and functions defined in the outer function will live longer than the outer function itself, if the inner function manages to survive beyond the life of the outer function. A closure is created when the inner function is somehow made available to any scope outside the outer function.
Example:
<script>
var createPet = function(name) {
var sex;
return {
setName: function(newName) {
name = newName;
},
getName: function() {
return name;
},
getSex: function() {
return sex;
},
setSex: function(newSex) {
if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
sex = newSex;
}
}
}
}
var pet = createPet("Vivie");
console.log(pet.getName()); // Vivie
console.log(pet.setName("Oliver"));
console.log(pet.setSex("male"));
console.log(pet.getSex()); // male
console.log(pet.getName()); // Oliver
</script>
In the code above, the name variable of the outer function is accessible to the inner functions, and there is no other way to access the inner variables except through the inner functions. The inner variables of the inner function act as safe stores for the inner functions. They hold "persistent", yet secure, data for the inner functions to work with. The functions do not even have to be assigned to a variable, or have a name.
read here for detail.
Explaining the practical use for a closure in JavaScript
When we create a function inside another function, we are creating a closure. Closures are powerful because they are capable of reading and manipulating the data of its outer functions. Whenever a function is invoked, a new scope is created for that call. The local variable declared inside the function belong to that scope and they can only be accessed from that function. When the function has finished the execution, the scope is usually destroyed.
A simple example of such function is this:
function buildName(name) {
const greeting = "Hello, " + name;
return greeting;
}
In above example, the function buildName() declares a local variable greeting and returns it. Every function call creates a new scope with a new local variable. After the function is done executing, we have no way to refer to that scope again, so it’s garbage collected.
But how about when we have a link to that scope?
Let’s look at the next function:
function buildName(name) {
const greeting = "Hello, " + name + " Welcome ";
const sayName = function() {
console.log(greeting);
};
return sayName;
}
const sayMyName = buildName("Mandeep");
sayMyName(); // Hello, Mandeep Welcome
The function sayName() from this example is a closure. The sayName() function has its own local scope (with variable welcome) and has also access to the outer (enclosing) function’s scope. In this case, the variable greeting from buildName().
After the execution of buildName is done, the scope is not destroyed in this case. The sayMyName() function still has access to it, so it won’t be garbage collected. However, there is no other way of accessing data from the outer scope except the closure. The closure serves as the gateway between the global context and the outer scope.
The JavaScript module pattern uses closures. Its nice pattern allows you to have something alike "public" and "private" variables.
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function(foo) {
console.log(foo);
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function(bar) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod(bar);
}
};
})();
I like Mozilla's function factory example.
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var addFive = makeAdder(5);
console.assert(addFive(2) === 7);
console.assert(addFive(-5) === 0);
This thread has helped me immensely in gaining a better understanding of how closures work.
I've since done some experimentation of my own and came up with this fairly simple code which may help some other people see how closures can be used in a practical way and how to use the closure at different levels to maintain variables similar to static and/or global variables without risk of them getting overwritten or confused with global variables.
This keeps track of button clicks, both at a local level for each individual button and a global level, counting every button click, contributing towards a single figure. Note I haven't used any global variables to do this, which is kind of the point of the exercise - having a handler that can be applied to any button that also contributes to something globally.
Please experts, do let me know if I've committed any bad practices here! I'm still learning this stuff myself.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Closures on button presses</title>
<script type="text/javascript">
window.addEventListener("load" , function () {
/*
Grab the function from the first closure,
and assign to a temporary variable
this will set the totalButtonCount variable
that is used to count the total of all button clicks
*/
var buttonHandler = buttonsCount();
/*
Using the result from the first closure (a function is returned)
assign and run the sub closure that carries the
individual variable for button count and assign to the click handlers
*/
document.getElementById("button1").addEventListener("click" , buttonHandler() );
document.getElementById("button2").addEventListener("click" , buttonHandler() );
document.getElementById("button3").addEventListener("click" , buttonHandler() );
// Now that buttonHandler has served its purpose it can be deleted if needs be
buttonHandler = null;
});
function buttonsCount() {
/*
First closure level
- totalButtonCount acts as a sort of global counter to count any button presses
*/
var totalButtonCount = 0;
return function () {
// Second closure level
var myButtonCount = 0;
return function (event) {
// Actual function that is called on the button click
event.preventDefault();
/*
Increment the button counts.
myButtonCount only exists in the scope that is
applied to each event handler and therefore acts
to count each button individually, whereas because
of the first closure totalButtonCount exists at
the scope just outside, it maintains a sort
of static or global variable state
*/
totalButtonCount++;
myButtonCount++;
/*
Do something with the values ... fairly pointless
but it shows that each button contributes to both
its own variable and the outer variable in the
first closure
*/
console.log("Total button clicks: "+totalButtonCount);
console.log("This button count: "+myButtonCount);
}
}
}
</script>
</head>
<body>
Button 1
Button 2
Button 3
</body>
</html>
There are various use cases of closures.Here, I am going to explain most important usage of Closure concept.
Closure can be used to create private methods and variables just like an object-oriented language like java, c++ and so on. Once you implemented private methods and variables, your variables defined inside a function won't be accessible by window object. This helps in data hiding and data security.
const privateClass = () => {
let name = "sundar";
function setName(changeName) {
name = changeName;
}
function getName() {
return name;
}
return {
setName: setName,
getName: getName,
};
};
let javaLikeObject = privateClass(); \\ similar to new Class() in OOPS.
console.log(javaLikeObject.getName()); \\this will give sundar
javaLikeObject.setName("suresh");
console.log(javaLikeObject.getName()); \\this will give suresh
Another real-life example of closure :
Create index.html:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Program with Javascript</title>
</head>
<body>
<p id="first"></p>
<p id="second"></p>
<button onclick="applyingConcepts()">Click</button>
<script src="./index.js"></script>
</body>
</html>
2)In index.js:
let count = 0;
return () => {
document.getElementById("first").innerHTML = count++;
};
})();
In this example, when you click a button, then your count will be updated on p#id.
Note: You might be wondering what's special in this code. When you inspect, you will notice that you can't change the value of count using the window object. This means you have declared private variable count so this prevents your states from being spoiled by the client.
I wrote an article a while back about how closures can be used to simplify event-handling code. It compares ASP.NET event handling to client-side jQuery.
http://www.hackification.com/2009/02/20/closures-simplify-event-handling-code/
Much of the code we write in front-end JavaScript is event-based — we define some behavior, then attach it to an event that is triggered by the user (such as a click or a keypress). Our code is generally attached as a callback: a single function which is executed in response to the event.
size12, size14, and size16 are now functions which will resize the body text to 12, 14, and 16 pixels, respectively. We can attach them to buttons (in this case links) as follows:
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
Fiddle
Closures are a useful way to create generators, a sequence incremented on-demand:
var foobar = function(i){var count = count || i; return function(){return ++count;}}
baz = foobar(1);
console.log("first call: " + baz()); //2
console.log("second call: " + baz()); //3
The differences are summarized as follows:
Anonymous functions Defined functions
Cannot be used as a method Can be used as a method of an object
Exists only in the scope in which it is defined Exists within the object it is defined in
Can only be called in the scope in which it is defined Can be called at any point in the code
Can be reassigned a new value or deleted Cannot be deleted or changed
References
AS3 Fundamentals: Functions
I'm trying to learn closures and I think the example that I have created is a practical use case. You can run a snippet and see the result in the console.
We have two separate users who have separate data. Each of them can see the actual state and update it.
function createUserWarningData(user) {
const data = {
name: user,
numberOfWarnings: 0,
};
function addWarning() {
data.numberOfWarnings = data.numberOfWarnings + 1;
}
function getUserData() {
console.log(data);
return data;
}
return {
getUserData: getUserData,
addWarning: addWarning,
};
}
const user1 = createUserWarningData("Thomas");
const user2 = createUserWarningData("Alex");
//USER 1
user1.getUserData(); // Returning data user object
user1.addWarning(); // Add one warning to specific user
user1.getUserData(); // Returning data user object
//USER2
user2.getUserData(); // Returning data user object
user2.addWarning(); // Add one warning to specific user
user2.addWarning(); // Add one warning to specific user
user2.getUserData(); // Returning data user object
Reference: Practical usage of closures
In practice, closures may create elegant designs, allowing customization of various calculations, deferred calls, callbacks, creating encapsulated scope, etc.
An example is the sort method of arrays which accepts the sort condition function as an argument:
[1, 2, 3].sort(function (a, b) {
... // Sort conditions
});
Mapping functionals as the map method of arrays which maps a new array by the condition of the functional argument:
[1, 2, 3].map(function (element) {
return element * 2;
}); // [2, 4, 6]
Often it is convenient to implement search functions with using functional arguments defining almost unlimited conditions for search:
someCollection.find(function (element) {
return element.someProperty == 'searchCondition';
});
Also, we may note applying functionals as, for example, a forEach method which applies a function to an array of elements:
[1, 2, 3].forEach(function (element) {
if (element % 2 != 0) {
alert(element);
}
}); // 1, 3
A function is applied to arguments (to a list of arguments — in apply, and to positioned arguments — in call):
(function () {
alert([].join.call(arguments, ';')); // 1;2;3
}).apply(this, [1, 2, 3]);
Deferred calls:
var a = 10;
setTimeout(function () {
alert(a); // 10, after one second
}, 1000);
Callback functions:
var x = 10;
// Only for example
xmlHttpRequestObject.onreadystatechange = function () {
// Callback, which will be called deferral ,
// when data will be ready;
// variable "x" here is available,
// regardless that context in which,
// it was created already finished
alert(x); // 10
};
Creation of an encapsulated scope for the purpose of hiding auxiliary objects:
var foo = {};
(function (object) {
var x = 10;
object.getX = function _getX() {
return x;
};
})(foo);
alert(foo.getX()); // Get closured "x" – 10
In the given sample, the value of the enclosed variable 'counter' is protected and can be altered only using the given functions (increment, decrement). Because it is in a closure,
var MyCounter = function (){
var counter = 0;
return {
increment:function () {return counter += 1;},
decrement:function () {return counter -= 1;},
get:function () {return counter;}
};
};
var x = MyCounter();
// Or
var y = MyCounter();
alert(x.get()); // 0
alert(x.increment()); // 1
alert(x.increment()); // 2
alert(y.increment()); // 1
alert(x.get()); // x is still 2
Everyone has explained the practical use cases of closure: the definition and a couple of examples.
I want to contribute a list of use cases of Closures:
suppose you want to count no of times a button is clicked; Closure is the best choice.
Throttling and Debounce
Currying
Memorize
Maintaining state in the async world
Functions like once
setTimeouts
Iterators
I have some JavaScript code that looks like:
function statechangedPostQuestion()
{
//alert("statechangedPostQuestion");
if (xmlhttp.readyState==4)
{
var topicId = xmlhttp.responseText;
setTimeout("postinsql(topicId)",4000);
}
}
function postinsql(topicId)
{
//alert(topicId);
}
I get an error that topicId is not defined
Everything was working before I used the setTimeout() function.
I want my postinsql(topicId) function to be called after some time.
What should I do?
setTimeout(function() {
postinsql(topicId);
}, 4000)
You need to feed an anonymous function as a parameter instead of a string, the latter method shouldn't even work per the ECMAScript specification but browsers are just lenient. This is the proper solution, don't ever rely on passing a string as a 'function' when using setTimeout() or setInterval(), it's slower because it has to be evaluated and it just isn't right.
UPDATE:
As Hobblin said in his comments to the question, now you can pass arguments to the function inside setTimeout using Function.prototype.bind().
Example:
setTimeout(postinsql.bind(null, topicId), 4000);
In modern browsers (ie IE11 and beyond), the "setTimeout" receives a third parameter that is sent as parameter to the internal function at the end of the timer.
Example:
var hello = "Hello World";
setTimeout(alert, 1000, hello);
More details:
https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setTimeout
http://arguments.callee.info/2008/11/10/passing-arguments-to-settimeout-and-setinterval/
After doing some research and testing, the only correct implementation is:
setTimeout(yourFunctionReference, 4000, param1, param2, paramN);
setTimeout will pass all extra parameters to your function so they can be processed there.
The anonymous function can work for very basic stuff, but within instance of a object where you have to use "this", there is no way to make it work.
Any anonymous function will change "this" to point to window, so you will lose your object reference.
This is a very old question with an already "correct" answer but I thought I'd mention another approach that nobody has mentioned here. This is copied and pasted from the excellent underscore library:
_.delay = function(func, wait) {
var args = slice.call(arguments, 2);
return setTimeout(function(){ return func.apply(null, args); }, wait);
};
You can pass as many arguments as you'd like to the function called by setTimeout and as an added bonus (well, usually a bonus) the value of the arguments passed to your function are frozen when you call setTimeout, so if they change value at some point between when setTimeout() is called and when it times out, well... that's not so hideously frustrating anymore :)
Here's a fiddle where you can see what I mean.
I recently came across the unique situation of needing to use a setTimeout in a loop. Understanding this can help you understand how to pass parameters to setTimeout.
Method 1
Use forEach and Object.keys, as per Sukima's suggestion:
var testObject = {
prop1: 'test1',
prop2: 'test2',
prop3: 'test3'
};
Object.keys(testObject).forEach(function(propertyName, i) {
setTimeout(function() {
console.log(testObject[propertyName]);
}, i * 1000);
});
I recommend this method.
Method 2
Use bind:
var i = 0;
for (var propertyName in testObject) {
setTimeout(function(propertyName) {
console.log(testObject[propertyName]);
}.bind(this, propertyName), i++ * 1000);
}
JSFiddle: http://jsfiddle.net/MsBkW/
Method 3
Or if you can't use forEach or bind, use an IIFE:
var i = 0;
for (var propertyName in testObject) {
setTimeout((function(propertyName) {
return function() {
console.log(testObject[propertyName]);
};
})(propertyName), i++ * 1000);
}
Method 4
But if you don't care about IE < 10, then you could use Fabio's suggestion:
var i = 0;
for (var propertyName in testObject) {
setTimeout(function(propertyName) {
console.log(testObject[propertyName]);
}, i++ * 1000, propertyName);
}
Method 5 (ES6)
Use a block scoped variable:
let i = 0;
for (let propertyName in testObject) {
setTimeout(() => console.log(testObject[propertyName]), i++ * 1000);
}
Though I would still recommend using Object.keys with forEach in ES6.
Hobblin already commented this on the question, but it should be an answer really!
Using Function.prototype.bind() is the cleanest and most flexible way to do this (with the added bonus of being able to set the this context):
setTimeout(postinsql.bind(null, topicId), 4000);
For more information see these MDN links:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041
https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/bind#With_setTimeout
You can pass the parameter to the setTimeout callback function as:
setTimeout(function, milliseconds, param1, param2, ...)
eg.
function myFunction() {
setTimeout(alertMsg, 3000, "Hello");
}
function alertMsg(message) {
alert(message)
}
Some answers are correct but convoluted.
I am answering this again, 4 years later, because I still run into overly complex code to solve exactly this question. There IS an elegant solution.
First of all, do not pass in a string as the first parameter when calling setTimeout because it effectively invokes a call to the slow "eval" function.
So how do we pass in a parameter to a timeout function? By using closure:
settopic=function(topicid){
setTimeout(function(){
//thanks to closure, topicid is visible here
postinsql(topicid);
},4000);
}
...
if (xhr.readyState==4){
settopic(xhr.responseText);
}
Some have suggested using anonymous function when calling the timeout function:
if (xhr.readyState==4){
setTimeout(function(){
settopic(xhr.responseText);
},4000);
}
The syntax works out. But by the time settopic is called, i.e. 4 seconds later, the XHR object may not be the same. Therefore it's important to pre-bind the variables.
I know its been 10 yrs since this question was asked, but still, if you have scrolled till here, i assume you're still facing some issue. The solution by Meder Omuraliev is the simplest one and may help most of us but for those who don't want to have any binding, here it is:
Use Param for setTimeout
setTimeout(function(p){
//p == param1
},3000,param1);
Use Immediately Invoked Function Expression(IIFE)
let param1 = 'demon';
setTimeout(function(p){
// p == 'demon'
},2000,(function(){
return param1;
})()
);
Solution to the question
function statechangedPostQuestion()
{
//alert("statechangedPostQuestion");
if (xmlhttp.readyState==4)
{
setTimeout(postinsql,4000,(function(){
return xmlhttp.responseText;
})());
}
}
function postinsql(topicId)
{
//alert(topicId);
}
Replace
setTimeout("postinsql(topicId)", 4000);
with
setTimeout("postinsql(" + topicId + ")", 4000);
or better still, replace the string expression with an anonymous function
setTimeout(function () { postinsql(topicId); }, 4000);
EDIT:
Brownstone's comment is incorrect, this will work as intended, as demonstrated by running this in the Firebug console
(function() {
function postinsql(id) {
console.log(id);
}
var topicId = 3
window.setTimeout("postinsql(" + topicId + ")",4000); // outputs 3 after 4 seconds
})();
Note that I'm in agreeance with others that you should avoid passing a string to setTimeout as this will call eval() on the string and instead pass a function.
My answer:
setTimeout((function(topicId) {
return function() {
postinsql(topicId);
};
})(topicId), 4000);
Explanation:
The anonymous function created returns another anonymous function. This function has access to the originally passed topicId, so it will not make an error. The first anonymous function is immediately called, passing in topicId, so the registered function with a delay has access to topicId at the time of calling, through closures.
OR
This basically converts to:
setTimeout(function() {
postinsql(topicId); // topicId inside higher scope (passed to returning function)
}, 4000);
EDIT: I saw the same answer, so look at his. But I didn't steal his answer! I just forgot to look. Read the explanation and see if it helps to understand the code.
The easiest cross browser solution for supporting parameters in setTimeout:
setTimeout(function() {
postinsql(topicId);
}, 4000)
If you don't mind not supporting IE 9 and lower:
setTimeout(postinsql, 4000, topicId);
https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout
I know it's old but I wanted to add my (preferred) flavour to this.
I think a pretty readable way to achieve this is to pass the topicId to a function, which in turn uses the argument to reference the topic ID internally. This value won't change even if topicId in the outside will be changed shortly after.
var topicId = xmlhttp.responseText;
var fDelayed = function(tid) {
return function() {
postinsql(tid);
};
}
setTimeout(fDelayed(topicId),4000);
or short:
var topicId = xmlhttp.responseText;
setTimeout(function(tid) {
return function() { postinsql(tid); };
}(topicId), 4000);
The answer by David Meister seems to take care of parameters that may change immediately after the call to setTimeout() but before the anonymous function is called. But it's too cumbersome and not very obvious. I discovered an elegant way of doing pretty much the same thing using IIFE (immediately inviked function expression).
In the example below, the currentList variable is passed to the IIFE, which saves it in its closure, until the delayed function is invoked. Even if the variable currentList changes immediately after the code shown, the setInterval() will do the right thing.
Without this IIFE technique, the setTimeout() function will definitely get called for each h2 element in the DOM, but all those calls will see only the text value of the last h2 element.
<script>
// Wait for the document to load.
$(document).ready(function() {
$("h2").each(function (index) {
currentList = $(this).text();
(function (param1, param2) {
setTimeout(function() {
$("span").text(param1 + ' : ' + param2 );
}, param1 * 1000);
})(index, currentList);
});
</script>
In general, if you need to pass a function as a callback with specific parameters, you can use higher order functions. This is pretty elegant with ES6:
const someFunction = (params) => () => {
//do whatever
};
setTimeout(someFunction(params), 1000);
Or if someFunction is first order:
setTimeout(() => someFunction(params), 1000);
Note that the reason topicId was "not defined" per the error message is that it existed as a local variable when the setTimeout was executed, but not when the delayed call to postinsql happened. Variable lifetime is especially important to pay attention to, especially when trying something like passing "this" as an object reference.
I heard that you can pass topicId as a third parameter to the setTimeout function. Not much detail is given but I got enough information to get it to work, and it's successful in Safari. I don't know what they mean about the "millisecond error" though. Check it out here:
http://www.howtocreate.co.uk/tutorials/javascript/timers
How i resolved this stage ?
just like that :
setTimeout((function(_deepFunction ,_deepData){
var _deepResultFunction = function _deepResultFunction(){
_deepFunction(_deepData);
};
return _deepResultFunction;
})(fromOuterFunction, fromOuterData ) , 1000 );
setTimeout wait a reference to a function, so i created it in a closure, which interprete my data and return a function with a good instance of my data !
Maybe you can improve this part :
_deepFunction(_deepData);
// change to something like :
_deepFunction.apply(contextFromParams , args);
I tested it on chrome, firefox and IE and it execute well, i don't know about performance but i needed it to be working.
a sample test :
myDelay_function = function(fn , params , ctxt , _time){
setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
var _deepResultFunction = function _deepResultFunction(){
//_deepFunction(_deepData);
_deepFunction.call( _deepCtxt , _deepData);
};
return _deepResultFunction;
})(fn , params , ctxt)
, _time)
};
// the function to be used :
myFunc = function(param){ console.log(param + this.name) }
// note that we call this.name
// a context object :
myObjet = {
id : "myId" ,
name : "myName"
}
// setting a parmeter
myParamter = "I am the outer parameter : ";
//and now let's make the call :
myDelay_function(myFunc , myParamter , myObjet , 1000)
// this will produce this result on the console line :
// I am the outer parameter : myName
Maybe you can change the signature to make it more complient :
myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
var _deepResultFunction = function _deepResultFunction(){
//_deepFunction(_deepData);
_deepFunction.apply( _deepCtxt , _deepData);
};
return _deepResultFunction;
})(fn , params , ctxt)
, _time)
};
// and try again :
for(var i=0; i<10; i++){
myNass_setTimeOut(console.log ,1000 , [i] , console)
}
And finaly to answer the original question :
myNass_setTimeOut( postinsql, 4000, topicId );
Hope it can help !
ps : sorry but english it's not my mother tongue !
this works in all browsers (IE is an oddball)
setTimeout( (function(x) {
return function() {
postinsql(x);
};
})(topicId) , 4000);
if you want to pass variable as param lets try this
if requirement is function and var as parmas then try this
setTimeout((param1,param2) => {
alert(param1 + param2);
postinsql(topicId);
},2000,'msg1', 'msg2')
if requirement is only variables as a params then try this
setTimeout((param1,param2) => { alert(param1 + param2) },2000,'msg1', 'msg2')
You can try this with ES5 and ES6
setTimeout is part of the DOM defined by WHAT WG.
https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html
The method you want is:—
handle = self.setTimeout( handler [, timeout [, arguments... ] ] )
Schedules a timeout to run handler after timeout milliseconds. Any
arguments are passed straight through to the handler.
setTimeout(postinsql, 4000, topicId);
Apparently, extra arguments are supported in IE10. Alternatively, you can use setTimeout(postinsql.bind(null, topicId), 4000);, however passing extra arguments is simpler, and that's preferable.
Historical factoid: In days of VBScript, in JScript, setTimeout's third parameter was the language, as a string, defaulting to "JScript" but with the option to use "VBScript". https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)
You can try default functionality of 'apply()' something like this, you can pass more number of arguments as your requirement in the array
function postinsql(topicId)
{
//alert(topicId);
}
setTimeout(
postinsql.apply(window,["mytopic"])
,500);
//Some function, with some arguments, that need to run with arguments
var a = function a(b, c, d, e){console.log(b, c, d, e);}
//Another function, where setTimeout using for function "a", this have the same arguments
var f = function f(b, c, d, e){ setTimeout(a.apply(this, arguments), 100);}
f(1,2,3,4); //run
//Another function, where setTimeout using for function "a", but some another arguments using, in different order
var g = function g(b, c, d, e){ setTimeout(function(d, c, b){a.apply(this, arguments);}, 100, d, c, b);}
g(1,2,3,4);
#Jiri Vetyska thanks for the post, but there is something wrong in your example.
I needed to pass the target which is hovered out (this) to a timed out function and I tried your approach. Tested in IE9 - does not work.
I also made some research and it appears that as pointed here the third parameter is the script language being used. No mention about additional parameters.
So, I followed #meder's answer and solved my issue with this code:
$('.targetItemClass').hover(ItemHoverIn, ItemHoverOut);
function ItemHoverIn() {
//some code here
}
function ItemHoverOut() {
var THIS = this;
setTimeout(
function () { ItemHoverOut_timeout(THIS); },
100
);
}
function ItemHoverOut_timeout(target) {
//do something with target which is hovered out
}
Hope, this is usefull for someone else.
As there is a problem with the third optonal parameter in IE and using closures prevents us from changing the variables (in a loop for example) and still achieving the desired result, I suggest the following solution.
We can try using recursion like this:
var i = 0;
var hellos = ["Hello World1!", "Hello World2!", "Hello World3!", "Hello World4!", "Hello World5!"];
if(hellos.length > 0) timeout();
function timeout() {
document.write('<p>' + hellos[i] + '<p>');
i++;
if (i < hellos.length)
setTimeout(timeout, 500);
}
We need to make sure that nothing else changes these variables and that we write a proper recursion condition to avoid infinite recursion.
// These are three very simple and concise answers:
function fun() {
console.log(this.prop1, this.prop2, this.prop3);
}
let obj = { prop1: 'one', prop2: 'two', prop3: 'three' };
let bound = fun.bind(obj);
setTimeout(bound, 3000);
// or
function funOut(par1, par2, par3) {
return function() {
console.log(par1, par2, par3);
}
};
setTimeout(funOut('one', 'two', 'three'), 5000);
// or
let funny = function(a, b, c) { console.log(a, b, c); };
setTimeout(funny, 2000, 'hello', 'worldly', 'people');
// These are three very simple and concise answers:
function fun() {
console.log(this.prop1, this.prop2, this.prop3);
}
let obj = { prop1: 'one', prop2: 'two', prop3: 'three' };
let bound = fun.bind(obj);
setTimeout(bound, 3000);
// or
function funOut(par1, par2, par3) {
return function() {
console.log(par1, par2, par3);
}
};
setTimeout(funOut('one', 'two', 'three'), 5000);
// or
let funny = function(a, b, c) { console.log(a, b, c); };
setTimeout(funny, 2000, 'hello', 'worldly', 'people');
I think you want:
setTimeout("postinsql(" + topicId + ")", 4000);
You have to remove quotes from your setTimeOut function call like this:
setTimeout(postinsql(topicId),4000);
Answering the question but by a simple addition function with 2 arguments.
var x = 3, y = 4;
setTimeout(function(arg1, arg2) {
return () => delayedSum(arg1, arg2);
}(x, y), 1000);
function delayedSum(param1, param2) {
alert(param1 + param2); // 7
}
I'm trying my hardest to wrap my head around JavaScript closures.
I get that by returning an inner function, it will have access to any variable defined in its immediate parent.
Where would this be useful to me? Perhaps I haven't quite got my head around it yet. Most of the examples I have seen online don't provide any real world code, just vague examples.
Can someone show me a real world use of a closure?
Is this one, for example?
var warnUser = function (msg) {
var calledCount = 0;
return function() {
calledCount++;
alert(msg + '\nYou have been warned ' + calledCount + ' times.');
};
};
var warnForTamper = warnUser('You can not tamper with our HTML.');
warnForTamper();
warnForTamper();
Suppose, you want to count the number of times user clicked a button on a webpage.
For this, you are triggering a function on onclick event of button to update the count of the variable
<button onclick="updateClickCount()">click me</button>
Now there could be many approaches like:
You could use a global variable, and a function to increase the counter:
var counter = 0;
function updateClickCount() {
++counter;
// Do something with counter
}
But, the pitfall is that any script on the page can change the counter, without calling updateClickCount().
Now, you might be thinking of declaring the variable inside the function:
function updateClickCount() {
var counter = 0;
++counter;
// Do something with counter
}
But, hey! Every time updateClickCount() function is called, the counter is set to 1 again.
Thinking about nested functions?
Nested functions have access to the scope "above" them.
In this example, the inner function updateClickCount() has access to the counter variable in the parent function countWrapper():
function countWrapper() {
var counter = 0;
function updateClickCount() {
++counter;
// Do something with counter
}
updateClickCount();
return counter;
}
This could have solved the counter dilemma, if you could reach the updateClickCount() function from the outside and you also need to find a way to execute counter = 0 only once not everytime.
Closure to the rescue! (self-invoking function):
var updateClickCount = (function(){
var counter = 0;
return function(){
++counter;
// Do something with counter
}
})();
The self-invoking function only runs once. It sets the counter to zero (0), and returns a function expression.
This way updateClickCount becomes a function. The "wonderful" part is that it can access the counter in the parent scope.
This is called a JavaScript closure. It makes it possible for a function to have "private" variables.
The counter is protected by the scope of the anonymous function, and can only be changed using the updateClickCount() function!
A more lively example on closures
<script>
var updateClickCount = (function(){
var counter = 0;
return function(){
++counter;
document.getElementById("spnCount").innerHTML = counter;
}
})();
</script>
<html>
<button onclick="updateClickCount()">click me</button>
<div> you've clicked
<span id="spnCount"> 0 </span> times!
</div>
</html>
Reference: JavaScript Closures
I've used closures to do things like:
a = (function () {
var privatefunction = function () {
alert('hello');
}
return {
publicfunction : function () {
privatefunction();
}
}
})();
As you can see there, a is now an object, with a method publicfunction ( a.publicfunction() ) which calls privatefunction, which only exists inside the closure. You can not call privatefunction directly (i.e. a.privatefunction() ), just publicfunction().
It's a minimal example, but maybe you can see uses to it? We used this to enforce public/private methods.
The example you give is an excellent one. Closures are an abstraction mechanism that allow you to separate concerns very cleanly. Your example is a case of separating instrumentation (counting calls) from semantics (an error-reporting API). Other uses include:
Passing parameterised behaviour into an algorithm (classic higher-order programming):
function proximity_sort(arr, midpoint) {
arr.sort(function(a, b) { a -= midpoint; b -= midpoint; return a*a - b*b; });
}
Simulating object oriented programming:
function counter() {
var a = 0;
return {
inc: function() { ++a; },
dec: function() { --a; },
get: function() { return a; },
reset: function() { a = 0; }
}
}
Implementing exotic flow control, such as jQuery's Event handling and AJAX APIs.
JavaScript closures can be used to implement throttle and debounce functionality in your application.
Throttling
Throttling puts a limit on as a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."
Code:
const throttle = (func, limit) => {
let isThrottling
return function() {
const args = arguments
const context = this
if (!isThrottling) {
func.apply(context, args)
isThrottling = true
setTimeout(() => isThrottling = false, limit)
}
}
}
Debouncing
Debouncing puts a limit on a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."
Code:
const debounce = (func, delay) => {
let debouncing
return function() {
const context = this
const args = arguments
clearTimeout(debouncing)
debouncing = setTimeout(() => func.apply(context, args), delay)
}
}
As you can see closures helped in implementing two beautiful features which every web application should have to provide smooth UI experience functionality.
Yes, that is a good example of a useful closure. The call to warnUser creates the calledCount variable in its scope and returns an anonymous function which is stored in the warnForTamper variable. Because there is still a closure making use of the calledCount variable, it isn't deleted upon the function's exit, so each call to the warnForTamper() will increase the scoped variable and alert the value.
The most common issue I see on Stack Overflow is where someone wants to "delay" use of a variable that is increased upon each loop, but because the variable is scoped then each reference to the variable would be after the loop has ended, resulting in the end state of the variable:
for (var i = 0; i < someVar.length; i++)
window.setTimeout(function () {
alert("Value of i was "+i+" when this timer was set" )
}, 10000);
This would result in every alert showing the same value of i, the value it was increased to when the loop ended. The solution is to create a new closure, a separate scope for the variable. This can be done using an instantly executed anonymous function, which receives the variable and stores its state as an argument:
for (var i = 0; i < someVar.length; i++)
(function (i) {
window.setTimeout(function () {
alert("Value of i was " + i + " when this timer was set")
}, 10000);
})(i);
In the JavaScript (or any ECMAScript) language, in particular, closures are useful in hiding the implementation of functionality while still revealing the interface.
For example, imagine you are writing a class of date utility methods and you want to allow users to look up weekday names by index, but you don't want them to be able to modify the array of names you use under the hood.
var dateUtil = {
weekdayShort: (function() {
var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
return function(x) {
if ((x != parseInt(x)) || (x < 1) || (x > 7)) {
throw new Error("invalid weekday number");
}
return days[x - 1];
};
}())
};
Note that the days array could simply be stored as a property of the dateUtil object, but then it would be visible to users of the script and they could even change it if they wanted, without even needing your source code. However, since it's enclosed by the anonymous function which returns the date lookup function it is only accessible by the lookup function so it is now tamperproof.
There is a section on Practical Closures at the Mozilla Developer Network.
If you're comfortable with the concept of instantiating a class in the object-oriented sense (i.e. to create an object of that class) then you're close to understanding closures.
Think of it this way: when you instantiate two Person objects you know that the class member variable "Name" is not shared between instances; each object has its own 'copy'. Similarly, when you create a closure, the free variable ('calledCount' in your example above) is bound to the 'instance' of the function.
I think your conceptual leap is slightly hampered by the fact that every function/closure returned by the warnUser function (aside: that's a higher-order function) closure binds 'calledCount' with the same initial value (0), whereas often when creating closures it is more useful to pass different initializers into the higher-order function, much like passing different values to the constructor of a class.
So, suppose when 'calledCount' reaches a certain value you want to end the user's session; you might want different values for that depending on whether the request comes in from the local network or the big bad internet (yes, it's a contrived example). To achieve this, you could pass different initial values for calledCount into warnUser (i.e. -3, or 0?).
Part of the problem with the literature is the nomenclature used to describe them ("lexical scope", "free variables"). Don't let it fool you, closures are more simple than would appear... prima facie ;-)
Here, I have a greeting that I want to say several times. If I create a closure, I can simply call that function to record the greeting. If I don't create the closure, I have to pass my name in every single time.
Without a closure (https://jsfiddle.net/lukeschlangen/pw61qrow/3/):
function greeting(firstName, lastName) {
var message = "Hello " + firstName + " " + lastName + "!";
console.log(message);
}
greeting("Billy", "Bob");
greeting("Billy", "Bob");
greeting("Billy", "Bob");
greeting("Luke", "Schlangen");
greeting("Luke", "Schlangen");
greeting("Luke", "Schlangen");
With a closure (https://jsfiddle.net/lukeschlangen/Lb5cfve9/3/):
function greeting(firstName, lastName) {
var message = "Hello " + firstName + " " + lastName + "!";
return function() {
console.log(message);
}
}
var greetingBilly = greeting("Billy", "Bob");
var greetingLuke = greeting("Luke", "Schlangen");
greetingBilly();
greetingBilly();
greetingBilly();
greetingLuke();
greetingLuke();
greetingLuke();
Another common use for closures is to bind this in a method to a specific object, allowing it to be called elsewhere (such as as an event handler).
function bind(obj, method) {
if (typeof method == 'string') {
method = obj[method];
}
return function () {
method.apply(obj, arguments);
}
}
...
document.body.addEventListener('mousemove', bind(watcher, 'follow'), true);
Whenever a mousemove event fires, watcher.follow(evt) is called.
Closures are also an essential part of higher-order functions, allowing the very common pattern of rewriting multiple similar functions as a single higher order function by parameterizing the dissimilar portions. As an abstract example,
foo_a = function (...) {A a B}
foo_b = function (...) {A b B}
foo_c = function (...) {A c B}
becomes
fooer = function (x) {
return function (...) {A x B}
}
where A and B aren't syntactical units but source code strings (not string literals).
See "Streamlining my javascript with a function" for a concrete example.
Here I have one simple example of the closure concept which we can use for in our E-commerce site or many others as well.
I am adding my JSFiddle link with the example. It contains a small product list of three items and one cart counter.
JSFiddle
// Counter closure implemented function;
var CartCouter = function(){
var counter = 0;
function changeCounter(val){
counter += val
}
return {
increment: function(){
changeCounter(1);
},
decrement: function(){
changeCounter(-1);
},
value: function(){
return counter;
}
}
}
var cartCount = CartCouter();
function updateCart() {
document.getElementById('cartcount').innerHTML = cartCount.value();
}
var productlist = document.getElementsByClassName('item');
for(var i = 0; i< productlist.length; i++){
productlist[i].addEventListener('click', function(){
if(this.className.indexOf('selected') < 0){
this.className += " selected";
cartCount.increment();
updateCart();
}
else{
this.className = this.className.replace("selected", "");
cartCount.decrement();
updateCart();
}
})
}
.productslist{
padding: 10px;
}
ul li{
display: inline-block;
padding: 5px;
border: 1px solid #DDD;
text-align: center;
width: 25%;
cursor: pointer;
}
.selected{
background-color: #7CFEF0;
color: #333;
}
.cartdiv{
position: relative;
float: right;
padding: 5px;
box-sizing: border-box;
border: 1px solid #F1F1F1;
}
<div>
<h3>
Practical use of a JavaScript closure concept/private variable.
</h3>
<div class="cartdiv">
<span id="cartcount">0</span>
</div>
<div class="productslist">
<ul>
<li class="item">Product 1</li>
<li class="item">Product 2</li>
<li class="item">Product 3</li>
</ul>
</div>
</div>
Use of Closures:
Closures are one of the most powerful features of JavaScript. JavaScript allows for the nesting of functions and grants the inner function full access to all the variables and functions defined inside the outer function (and all other variables and functions that the outer function has access to). However, the outer function does not have access to the variables and functions defined inside the inner function.
This provides a sort of security for the variables of the inner function. Also, since the inner function has access to the scope of the outer function, the variables and functions defined in the outer function will live longer than the outer function itself, if the inner function manages to survive beyond the life of the outer function. A closure is created when the inner function is somehow made available to any scope outside the outer function.
Example:
<script>
var createPet = function(name) {
var sex;
return {
setName: function(newName) {
name = newName;
},
getName: function() {
return name;
},
getSex: function() {
return sex;
},
setSex: function(newSex) {
if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
sex = newSex;
}
}
}
}
var pet = createPet("Vivie");
console.log(pet.getName()); // Vivie
console.log(pet.setName("Oliver"));
console.log(pet.setSex("male"));
console.log(pet.getSex()); // male
console.log(pet.getName()); // Oliver
</script>
In the code above, the name variable of the outer function is accessible to the inner functions, and there is no other way to access the inner variables except through the inner functions. The inner variables of the inner function act as safe stores for the inner functions. They hold "persistent", yet secure, data for the inner functions to work with. The functions do not even have to be assigned to a variable, or have a name.
read here for detail.
Explaining the practical use for a closure in JavaScript
When we create a function inside another function, we are creating a closure. Closures are powerful because they are capable of reading and manipulating the data of its outer functions. Whenever a function is invoked, a new scope is created for that call. The local variable declared inside the function belong to that scope and they can only be accessed from that function. When the function has finished the execution, the scope is usually destroyed.
A simple example of such function is this:
function buildName(name) {
const greeting = "Hello, " + name;
return greeting;
}
In above example, the function buildName() declares a local variable greeting and returns it. Every function call creates a new scope with a new local variable. After the function is done executing, we have no way to refer to that scope again, so it’s garbage collected.
But how about when we have a link to that scope?
Let’s look at the next function:
function buildName(name) {
const greeting = "Hello, " + name + " Welcome ";
const sayName = function() {
console.log(greeting);
};
return sayName;
}
const sayMyName = buildName("Mandeep");
sayMyName(); // Hello, Mandeep Welcome
The function sayName() from this example is a closure. The sayName() function has its own local scope (with variable welcome) and has also access to the outer (enclosing) function’s scope. In this case, the variable greeting from buildName().
After the execution of buildName is done, the scope is not destroyed in this case. The sayMyName() function still has access to it, so it won’t be garbage collected. However, there is no other way of accessing data from the outer scope except the closure. The closure serves as the gateway between the global context and the outer scope.
The JavaScript module pattern uses closures. Its nice pattern allows you to have something alike "public" and "private" variables.
var myNamespace = (function () {
var myPrivateVar, myPrivateMethod;
// A private counter variable
myPrivateVar = 0;
// A private function which logs any arguments
myPrivateMethod = function(foo) {
console.log(foo);
};
return {
// A public variable
myPublicVar: "foo",
// A public function utilizing privates
myPublicFunction: function(bar) {
// Increment our private counter
myPrivateVar++;
// Call our private method using bar
myPrivateMethod(bar);
}
};
})();
I like Mozilla's function factory example.
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var addFive = makeAdder(5);
console.assert(addFive(2) === 7);
console.assert(addFive(-5) === 0);
This thread has helped me immensely in gaining a better understanding of how closures work.
I've since done some experimentation of my own and came up with this fairly simple code which may help some other people see how closures can be used in a practical way and how to use the closure at different levels to maintain variables similar to static and/or global variables without risk of them getting overwritten or confused with global variables.
This keeps track of button clicks, both at a local level for each individual button and a global level, counting every button click, contributing towards a single figure. Note I haven't used any global variables to do this, which is kind of the point of the exercise - having a handler that can be applied to any button that also contributes to something globally.
Please experts, do let me know if I've committed any bad practices here! I'm still learning this stuff myself.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Closures on button presses</title>
<script type="text/javascript">
window.addEventListener("load" , function () {
/*
Grab the function from the first closure,
and assign to a temporary variable
this will set the totalButtonCount variable
that is used to count the total of all button clicks
*/
var buttonHandler = buttonsCount();
/*
Using the result from the first closure (a function is returned)
assign and run the sub closure that carries the
individual variable for button count and assign to the click handlers
*/
document.getElementById("button1").addEventListener("click" , buttonHandler() );
document.getElementById("button2").addEventListener("click" , buttonHandler() );
document.getElementById("button3").addEventListener("click" , buttonHandler() );
// Now that buttonHandler has served its purpose it can be deleted if needs be
buttonHandler = null;
});
function buttonsCount() {
/*
First closure level
- totalButtonCount acts as a sort of global counter to count any button presses
*/
var totalButtonCount = 0;
return function () {
// Second closure level
var myButtonCount = 0;
return function (event) {
// Actual function that is called on the button click
event.preventDefault();
/*
Increment the button counts.
myButtonCount only exists in the scope that is
applied to each event handler and therefore acts
to count each button individually, whereas because
of the first closure totalButtonCount exists at
the scope just outside, it maintains a sort
of static or global variable state
*/
totalButtonCount++;
myButtonCount++;
/*
Do something with the values ... fairly pointless
but it shows that each button contributes to both
its own variable and the outer variable in the
first closure
*/
console.log("Total button clicks: "+totalButtonCount);
console.log("This button count: "+myButtonCount);
}
}
}
</script>
</head>
<body>
Button 1
Button 2
Button 3
</body>
</html>
There are various use cases of closures.Here, I am going to explain most important usage of Closure concept.
Closure can be used to create private methods and variables just like an object-oriented language like java, c++ and so on. Once you implemented private methods and variables, your variables defined inside a function won't be accessible by window object. This helps in data hiding and data security.
const privateClass = () => {
let name = "sundar";
function setName(changeName) {
name = changeName;
}
function getName() {
return name;
}
return {
setName: setName,
getName: getName,
};
};
let javaLikeObject = privateClass(); \\ similar to new Class() in OOPS.
console.log(javaLikeObject.getName()); \\this will give sundar
javaLikeObject.setName("suresh");
console.log(javaLikeObject.getName()); \\this will give suresh
Another real-life example of closure :
Create index.html:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Program with Javascript</title>
</head>
<body>
<p id="first"></p>
<p id="second"></p>
<button onclick="applyingConcepts()">Click</button>
<script src="./index.js"></script>
</body>
</html>
2)In index.js:
let count = 0;
return () => {
document.getElementById("first").innerHTML = count++;
};
})();
In this example, when you click a button, then your count will be updated on p#id.
Note: You might be wondering what's special in this code. When you inspect, you will notice that you can't change the value of count using the window object. This means you have declared private variable count so this prevents your states from being spoiled by the client.
I wrote an article a while back about how closures can be used to simplify event-handling code. It compares ASP.NET event handling to client-side jQuery.
http://www.hackification.com/2009/02/20/closures-simplify-event-handling-code/
Much of the code we write in front-end JavaScript is event-based — we define some behavior, then attach it to an event that is triggered by the user (such as a click or a keypress). Our code is generally attached as a callback: a single function which is executed in response to the event.
size12, size14, and size16 are now functions which will resize the body text to 12, 14, and 16 pixels, respectively. We can attach them to buttons (in this case links) as follows:
function makeSizer(size) {
return function() {
document.body.style.fontSize = size + 'px';
};
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;
Fiddle
Closures are a useful way to create generators, a sequence incremented on-demand:
var foobar = function(i){var count = count || i; return function(){return ++count;}}
baz = foobar(1);
console.log("first call: " + baz()); //2
console.log("second call: " + baz()); //3
The differences are summarized as follows:
Anonymous functions Defined functions
Cannot be used as a method Can be used as a method of an object
Exists only in the scope in which it is defined Exists within the object it is defined in
Can only be called in the scope in which it is defined Can be called at any point in the code
Can be reassigned a new value or deleted Cannot be deleted or changed
References
AS3 Fundamentals: Functions
I'm trying to learn closures and I think the example that I have created is a practical use case. You can run a snippet and see the result in the console.
We have two separate users who have separate data. Each of them can see the actual state and update it.
function createUserWarningData(user) {
const data = {
name: user,
numberOfWarnings: 0,
};
function addWarning() {
data.numberOfWarnings = data.numberOfWarnings + 1;
}
function getUserData() {
console.log(data);
return data;
}
return {
getUserData: getUserData,
addWarning: addWarning,
};
}
const user1 = createUserWarningData("Thomas");
const user2 = createUserWarningData("Alex");
//USER 1
user1.getUserData(); // Returning data user object
user1.addWarning(); // Add one warning to specific user
user1.getUserData(); // Returning data user object
//USER2
user2.getUserData(); // Returning data user object
user2.addWarning(); // Add one warning to specific user
user2.addWarning(); // Add one warning to specific user
user2.getUserData(); // Returning data user object
Reference: Practical usage of closures
In practice, closures may create elegant designs, allowing customization of various calculations, deferred calls, callbacks, creating encapsulated scope, etc.
An example is the sort method of arrays which accepts the sort condition function as an argument:
[1, 2, 3].sort(function (a, b) {
... // Sort conditions
});
Mapping functionals as the map method of arrays which maps a new array by the condition of the functional argument:
[1, 2, 3].map(function (element) {
return element * 2;
}); // [2, 4, 6]
Often it is convenient to implement search functions with using functional arguments defining almost unlimited conditions for search:
someCollection.find(function (element) {
return element.someProperty == 'searchCondition';
});
Also, we may note applying functionals as, for example, a forEach method which applies a function to an array of elements:
[1, 2, 3].forEach(function (element) {
if (element % 2 != 0) {
alert(element);
}
}); // 1, 3
A function is applied to arguments (to a list of arguments — in apply, and to positioned arguments — in call):
(function () {
alert([].join.call(arguments, ';')); // 1;2;3
}).apply(this, [1, 2, 3]);
Deferred calls:
var a = 10;
setTimeout(function () {
alert(a); // 10, after one second
}, 1000);
Callback functions:
var x = 10;
// Only for example
xmlHttpRequestObject.onreadystatechange = function () {
// Callback, which will be called deferral ,
// when data will be ready;
// variable "x" here is available,
// regardless that context in which,
// it was created already finished
alert(x); // 10
};
Creation of an encapsulated scope for the purpose of hiding auxiliary objects:
var foo = {};
(function (object) {
var x = 10;
object.getX = function _getX() {
return x;
};
})(foo);
alert(foo.getX()); // Get closured "x" – 10
In the given sample, the value of the enclosed variable 'counter' is protected and can be altered only using the given functions (increment, decrement). Because it is in a closure,
var MyCounter = function (){
var counter = 0;
return {
increment:function () {return counter += 1;},
decrement:function () {return counter -= 1;},
get:function () {return counter;}
};
};
var x = MyCounter();
// Or
var y = MyCounter();
alert(x.get()); // 0
alert(x.increment()); // 1
alert(x.increment()); // 2
alert(y.increment()); // 1
alert(x.get()); // x is still 2
Everyone has explained the practical use cases of closure: the definition and a couple of examples.
I want to contribute a list of use cases of Closures:
suppose you want to count no of times a button is clicked; Closure is the best choice.
Throttling and Debounce
Currying
Memorize
Maintaining state in the async world
Functions like once
setTimeouts
Iterators
Here's an example of a situation where a simple JS loop does not behave as expected, because of the loop variable not being in a separate scope.
The solution often presented is to construct an unpleasant-looking bit of loop code that looks like this:
for (var i in obj) {
(function() {
... obj[i] ...
// this new shadowed i here is now no longer getting changed by for loop
})(i);
}
My question is, could this be improved upon? Could I use this:
Object.prototype.each = function (f) {
for (var i in this) {
f(i,this[i]);
}
};
// leading to this somewhat more straightforward invocation
obj.each(
function(i,v) {
... v ...
// alternatively, v is identical to
... obj[i] ...
}
);
when I ascertain that I need a "scoped loop"? It is somewhat cleaner looking and should have similar performance to the regular for-loop (since it uses it the same way).
Update: It seems that doing things with Object.prototype is a huge no-no because it breaks pretty much everything.
Here is a less intrusive implementation:
function each (obj,f) {
for (var i in obj) {
f(i,obj[i]);
}
}
The invocation changes very slightly to
each(obj,
function(i,v) {
... v ...
}
);
So I guess I've answered my own question, if jQuery does it this way, can't really go wrong. Any issues I've overlooked though would warrant an answer.
Your answer pretty much covers it, but I think a change in your original loop is worth noting as it makes it reasonable to use a normal for loop when the each() function isn't handy, for whatever reason.
Update: Changed to use an example that's similar to the example referenced by the question to compare the different approaches. The example had to be adjusted because the each() function requires a populated array to iterate over.
Assuming the following setup:
var vals = ['a', 'b', 'c', 'd'],
max = vals.length,
closures = [],
i;
Using the example from the question, the original loop ends up creating 2n functions (where n is the number of iterations) because two functions are created during each iteration:
for (i = 0; i < max; i++) {
closures[i] = (function(idx, val) { // 1st - factoryFn - captures the values as arguments
return function() { // 2nd - alertFn - uses the arguments instead
alert(idx + ' -> ' + val); // of the variables
};
})(i, vals[i]);
}
This can be reduced to creating only n + 1 functions by creating the factory function once, before the loop is started, and then reusing it:
var factoryFn = function(idx, val) {
return function() {
alert(idx + ' -> ' + val);
};
};
for (i = 0; i < max; i++) {
closures[i] = factoryFn(i, vals[i]);
}
This is nearly equivalent to how the each() function might be used in this situation, which would also result in a total of n + 1 functions created. The factory function is created once and passed immediately as an argument to each().
each(vals, function(idx, val) {
closures[idx] = function() {
alert(idx + ' -> ' + val);
};
});
FWIW, I think a benefit to using each() is the code is a bit shorter and creating the factory function right as it's passed into the each() function clearly illustrates this is its only use. A benefit of the for loop version, IMO, is the code that does the loop is right there so it's nature and behavior is completely transparent while the each() function might be defined in a different file, written by someone else, etc.
Global Scope
When something is global means that it is accessible from anywhere in your code. Take this for example:
var monkey = "Gorilla";
function greetVisitor () {
return alert("Hello dear blog reader!");
}
If that code was being run in a web browser, the function scope would be window, thus making it
available to everything running in that web browser window.
Local Scope
As opposed to the global scope, the local scope is when something is just defined and accessible in a
certain part of the code, like a function. For instance;
function talkDirty () {
var saying = "Oh, you little VB lover, you";
return alert(saying);
}
alert(saying); // Throws an error
If you take a look at the code above, the variable saying is only available within the talkDirty
function. Outside of it it isn’t defined at all. Note of caution: if you were to declare saying without
the var keyword preceding it, it would automatically become a global variable.
What this also means is that if you have nested functions, the inner function will have access to the
containing functions variables and functions:
function saveName (firstName) {
function capitalizeName () {
return firstName.toUpperCase();
}
var capitalized = capitalizeName();
return capitalized;
}
alert(saveName("Robert")); // Returns "ROBERT"
As you just saw, the inner function capitalizeName didn’t need any parameter sent in, but had complete
access to the parameter firstName in the outer saveName function. For clarity, let’s take another
example:
function siblings () {
var siblings = ["John", "Liza", "Peter"];
function siblingCount () {
var siblingsLength = siblings.length;
return siblingsLength;
}
function joinSiblingNames () {
return "I have " + siblingCount() + " siblings:\n\n" + siblings.join("\n");
}
return joinSiblingNames();
}
alert(siblings()); // Outputs "I have 3 siblings: John Liza Peter"
As you just saw, both inner functions have access to the siblings array in the containing function, and
each inner function have access to the other inner functions on the same level (in this case,
joinSiblingNames can access siblingCount). However, the variable siblingsLength in the siblingCount is
only available within that function, i.e. that scope.
I'm trying to write some JS replicating jQuery's fadeIn and fadeOut functions. Here's the code I have so far:
function fadeIn(elem, d, callback)
{
var duration = d || 1000;
var steps = Math.floor(duration / 50);
setOpacity(elem,0);
elem.style.display = '';
for (var i = 1; i <= steps; i++)
{
console.log(i/steps + ', ' + (i/steps) * duration);
setTimeout('setOpacity("elem", '+(i / steps)+' )', (i/steps) * duration);
}
if (callback)
setTimeout(callback,d);
}
function setOpacity(elem, level)
{
console.log(elem);
return;
elem.style.opacity = level;
elem.style.MozOpacity = level;
elem.style.KhtmlOpacity = level;
elem.style.filter = "alpha(opacity=" + (level * 100) + ");";
}
I'm having troubles with the first setTimeout call - I need to pass the object 'elem' (which is a DOM element) to the function setOpacity. Passing the 'level' variable works just fine... however, I'm getting "elem is not defined" errors. I think that's because by the time any of the setOpacity calls actually run, the initial fadeIn function has finished and so the variable elem no longer exists.
To mitigate this, I tried another approach:
setTimeout(function() { setOpacity(elem, (i / steps));}, (i/steps) * duration);
The trouble now is that when the function is called, (i/steps) is now always 1.05 instead of incrementing from 0 to 1.
How can I pass the object in question to setOpacity while properly stepping up the opacity level?
Your "another approach" is correct, this is how it's usually done.
And as for the problem of i always being a constant, that's how closures work!
You see, when you create this function that does something with i (like function() { alert(i); }), that function, as they say, 'captures', or 'binds' the variable i, so that variable i does not die after the loop is finished, but continues to live on and is still referenced from that function.
To demonstrate this concept, consider the following code:
var i = 5;
var fn = function() { alert(i); };
fn(); // displays "5"
i = 6;
fn(); // displays "6"
When it is written in this way, the concept becomes a bit more evident, doesn't it? Since you're changing the variable in the loop, after the loop is finished the variable retains it's last value of (1+steps) - and that's exactly what your function sees when it starts executing.
To work around this, you have to create another function that will return a function. Yes, I know, kind of mind-blowing, but bear with me. Consider the revised version of my example:
function createFn( theArgument )
{
return function() { alert( theArgument ); };
}
var i = 5;
var fn = createFn( i );
fn(); // displays "5"
i = 6;
fn(); // still displays "5". Voila!
This works, because the fn function no longer binds the variable i. Instead, now it binds another variable - theArgument, which has nothing to do with i, other than they have the same value at the moment of calling createFn. Now you can change your i all you want - theArgument will be invincible.
Applying this to your code, here's how you should modify it:
function createTimeoutHandler( elemArg, iDivStepsArg )
{
return function() { setOpacity( elemArg, iDivStepsArg ); };
}
for (var i = 1; i <= steps; i++)
{
console.log(i/steps + ', ' + (i/steps) * duration);
setTimeout( createTimeoutHandler( elem, i/steps ), (i/steps) * duration);
}
Your first approach is evaluating code at runtime. You are most likely right about why it's failing (elem is not in the scope in which the code is eval'd). Using any form of eval() (and setTimeout(string, ...) is a form of eval()) is a general bad idea in Javascript, it's much better to create a function as in your second approach.
To understand why your second approach is failing you need to understand scopes and specifically closures. When you create that function, it grabs a reference to the i variable from the fadeIn function's scope.
When you later run the function, it uses that reference to refer back to the i from fadeIn's scope. By the time this happens however, the loop is over so you'll forever just get i being whatever it was when that loop ended.
What you should do is re-engineer it so that instead of creating many setTimeouts at once (which is inefficient) you instead tell your setTimeout callback function to set the next Timeout (or you could use setInterval) and do the incrementing if your values inside that callback function.