Javascript closures and side effects in plain English? (separately)
Asked Answered
P

6

32

I've been reading some JavaScript books and I always hear about closures and side effects. For some reason I can't understand what they really are. Can anyone explain to me what they are in plain English plus examples? (as you were explaining it to someone with the programming level of a graphic designer).

Prieto answered 14/11, 2011 at 22:27 Comment(4)
Please clarify: Are you asking for an explanation for closures and and seperately for an explanation of side effects? Or about both combined?Alkmaar
@delnan sorry I modified the title.Prieto
Then see #111602 and remove the closures part, it'd be a duplicate. Side effects aren't exactly new either, but I'm not aware of anything specific on SO, so I'm not voting to close for now.Alkmaar
This is two questions, one about side effects and one about closures, and should be kept separate. As delnan notes, closures have been covered before, so it's best to make this question about side-effects and refer to the other question for an explanation about closures.Staub
B
45

Side effects are the easier concept. A "pure function" is a function that maps its input value(s) into an output value function plus(x, y) { return x + y; }. A "side effect" is any effect other than that return value. So, for instance:

function plusWithSideEffects(x, y) {
  alert('This is a side effect'); 
  return x + y;
} 

has the side effect of raising an alert dialog (and requiring user interaction). Every code function has some side effects (they all consume memory and take time, if nothing else), but when people talk about side effects, they are often most concerned with either IO (like the alert dialog above) or the writing of state that lives beyond the execution period of the function.

The challenge with side effects is that they make functions harder to reason about and to reuse. (It's much easier to reason and reuse functions that are as close to "pure functions" as possible, since they tend to "do one thing well.")

Buttocks answered 14/11, 2011 at 22:44 Comment(6)
For "programming level of a graphic designer" it's a real answer.Buttocks
I'm not down voting this because the answer does answer the question, but, I don't like the def keyword used in the example as it's not a javascript reserved word, it's a python thing isn't it?Marcellmarcella
@Marcellmarcella the def is not Python-specific and the example would not work in Python as it has braces and not proper indentation. This is more of a notation in pseudo-code or even in mathematics to show what a pure function is.Slash
@Haralan Dobrev, ah thanks for clearing that up for meMarcellmarcella
Is the use of def here really justified? This is a Javascript-specific question and the code otherwise is entirely Javascript. There's nothing pseudo about it other than the def. Just change it to function...Fragmental
@DG, I agree completely with you. I have changed def to function in a proposed edit now.Giesser
S
9

Functions with side effects do something other than returning a value (though they may do that as well). If you can replace all function calls for given arguments with the value for those arguments and the program has the same behavior, there are no side effects. This requires that the function always return the same value for given arguments.

That is, suppose f(1,2) == 12. If you can always replace f(1,2) with 12 and the program behaves the same way, then f has no side effects for those arguments. On the other hand, if in one place f(1,2) == 12 and another f(1,2) == 13, then f has side effects. Similarly, if the program stopped sending an email after replacing f(1,2) with 12, then f has side effects. Generally, if f(x,y) == z (where z depends on x and y) and you can always replace every f(x,y) call with z, then f has no side effects.

Some simple functions with side effects:

// doesn't always return the same value
function counter() {
    // globals are bad
    return ++x;
}
// omitting calls to `say` change logging behavior
function say(x) {
    console.log(x);
    return x;
}
Staub answered 14/11, 2011 at 23:47 Comment(0)
J
6

Side-effect:

Think of a side-effect as something that does two things at once. For example:

Classic example of a side effect:

var i = 1;
var j = i++;

The side effect happens at i++. What happens here is j becomes 1 and then i gets incremented and becomes 2. In other words, two things happened and the side-effect was that i became 2.

Closure:

Visualize a chain of links like this: <><><><><><><>. Imagine that the name of this chain of links is called the scope chain. Then imagine that all these links connect objects together like this: <>object<>object<>object<>. Now, keep in mind the following:

(1) All scope chains begin with the global object.

(2) When a function is defined, a scope chain for that function is stored.

(3) When a function is invoked, it creates a new object and adds that to the scope chain.

Now, please look at the following example:

function counter () { // define counter
                   var count = 0;
                   return function () { return count + 1;}; // define anonymous function
                   };
var count = counter(); // invoke counter

In this example, when counter() is defined, the scope chain for counter looks like this: <>global object<>. Then, when counter() is invoked, the scope chain looks like this: <>global object<>counter object<>. After that, the function with no name (called an anonymous function) inside counter is defined and invoked. The scope chain for the anonymous function once invoked looks like this: <>global object<>counter object<>anonymous function object<>

Heres were the closure part comes in. If you notice, the anonymous function is using the variable count which was defined outside of it. The reason is because the anonymous function can access any variables defined in its scope chain. This is what a closure is, a function along with references to any variables in its stored scope chain.

However, in the above example, once the functions return, the objects created at invocation are discarded so there really is no point. Now look at the following:

function counter () { // define counter
                   var count = 0;
                   function f() { return count + 1;}; // define f
                   return f; // return f
                   };
var count = counter(); // invoke counter

In this example, I am returning a function named f and assign that to the variable count. Now the variable count holds a reference to the entire scope chain and it does not get discarded. In other words the variable count stores the scope chain like this: <>global object<>counter object<>anonymous function object<>. This is the power of closures, you can hold a reference to a scope chain, and call it like this: count().

Jarlathus answered 14/11, 2011 at 23:7 Comment(2)
The closure portion of this answer is incorrect. JavaScript has static scope, which means that the scope chain of a function is defined at function definition, not function invocation. The example works because the anonymous function is defined each time counter is invoked, meaning that each returned function will have a scope chain with a different activation object for counter, and thus a different set of local variables (such as count). See this answer for more info.Northington
@josh3736: Thanks for the comment. I changed my answer, please advise if anything is wrong. Also, I wanted to comment that, for a global function declaration, the function will only have a reference to a scope chain that contains the global object. Not until you invoke it will it have a reference to the activation object.Jarlathus
B
0

Exemple

function outer() {
    var outerVar;

    var func = function() {
        var innerVar
        ...
        x = innerVar + outerVar
    }
    return func
}

When outer() die, function func() continue livе and this use practical

Boden answered 14/11, 2011 at 22:33 Comment(0)
S
0

I am new to JavaScript, and will not try to talk of closures. However my newness to JavaScript makes me quite aware of the use of side effect that are impossible in my usual programming language (Erlang).

Side effects seem to be a usual way to change state in JavaScript. Take for example this example from the w3cschools.com website:

<script>
function myFunction() {
    document.getElementById("demo").innerHTML = "Paragraph changed.";
}
</script>

Here there is no input parameters or return value, instead the contents of the document get changed as they are global in scope to the function. If you were to write this in Erlang for example, the document would be passed in as a parameter, and the new document state would be returned. A person reading the calling program would see a document passed in and an altered document being returned.

Seeing functions called that to not return explicit new state should alert to programmer to probable use of sideeffects.

Sloop answered 28/6, 2015 at 9:49 Comment(0)
A
0

Mainly side effects are the interactions with the outside world from inside of the function. Some examples of the side effects are:- API Calls or HTTP requests, data mutations, Printing to a screen or console, DOM Query/Manipulation. Example :

var a = 12
function addTwo(){
   a = a + 2; // side-effect

}
addTwo()

Closures

According to MDN,

A closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time.

Example :

function outer(){
  var a = 12; // Declared in outer function 
  function addTwo(){ // closure function
    a = a + 2; // acessing outer function property
    console.log(a)
  }
  addTwo();
 }
 outer()
Aloisius answered 21/3, 2020 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.