DEV Community

Cover image for Day 8 : Learning JS fundamentals, Part -3
Gaurav-Shekhawat
Gaurav-Shekhawat

Posted on

Day 8 : Learning JS fundamentals, Part -3

Closures

Closure is when a function "remembers" the variables outside of it, even if you pass that function elsewhere.

function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5);
var add10 = makeAdder(10);

console.log(add5(2));  // 7
console.log(add10(2)); // 12
Enter fullscreen mode Exit fullscreen mode

The full reference can be found on - MDN

Alt Tefxt

In the above example, the variable question will remian alive, even after 100ms of execution of parent function.

Example - 2

Alt Tdext

Here, the function holdYourQuestion will remember the question, even if it is called at an entire different time on an entire differnet place.

this keyword

It is all about the call, it is not the definition of the function, it is not where the function is, none of that matters, it is only how the function was called that determines where the this keyword will be pointing to.

A this-aware function can thus have a different context each time it's called, which makes it more flexible & reusable.

Alt Texft

Alt dText


DOUBT

Prototypes in js

Discussion (10)

Collapse
marzelin profile image
Marc Ziel

In languages that treat functions as first class objects (to put it simply: functions are values) there might be a situation when a function outlives the function call in which it was created.

So we need to make sure that the inner function can refer to local variables of the outer function even if the outer function returned (finished executing) to maintain lexical scope.

This means that environment in which function was created must be preserved somewhere.

And that's what a closure is: a function bundled with its lexical environment.

Collapse
gauravshekhawat profile image
Gaurav-Shekhawat Author

Thanks, as always, spent the entire day trying to learn it then wrote whatever I understood till evening with the intention of continuing from there the next day. But your single comment was more fruitful than me wondering entire day looking at differnet sites.

Collapse
gauravshekhawat profile image
Gaurav-Shekhawat Author

I was just curious, if we pass the function let's say to another function, then is the lexical environment of the function passed with it or it is referred from the original parent function every time.

Collapse
marzelin profile image
Marc Ziel

Every JS function is a closure so it has its lexical environment "attached" internally.

You can think of it as a special, internal property [[Scope]] on a function that it uses whenever it needs to access external variables.

It's quite similar to object [[Prototype]] used to look up for properties whenever they can't be found on an object itself but unlike [[Scope]] you can access [[Prototype]] with __proto__ or Object.getPrototypeOf() so it can be easier to understand.

Both of them might look magical at first but they're just chains of connected structures looked up in order from closest to farthest in search for properties/variables.

Thread Thread
gauravshekhawat profile image
Gaurav-Shekhawat Author

oh, thanks!!
your comment always motivates me to dig much deeper into the topic

Thread Thread
marzelin profile image
Marc Ziel

You're welcome.

Collapse
marzelin profile image
Marc Ziel

It is all about the call, it is not the definition of the function, it is not where the function is, none of that matters, it is only how the function was called that determines where the this keyword will be pointing to.

This isn't entirely true. You can bind a function and that sets this at creation time. Only new operator can change what this refers to on a binded function at call time.

Collapse
gauravshekhawat profile image
Gaurav-Shekhawat Author

Can you please elaborate, I am not able to understand. A link or something regarding the same will suffice.

Collapse
marzelin profile image
Marc Ziel

If you bind a function:

const bound = function () {
   console.log(this);
}.bind({type: "bound"});
Enter fullscreen mode Exit fullscreen mode

then no matter how you call the function (except new).
You can use .:

const o = { bound, type: "dot notation" };
o.bound();
Enter fullscreen mode Exit fullscreen mode

apply or call:

bound.call({type: "call"});
Enter fullscreen mode Exit fullscreen mode

or even call it directly:

bound();
Enter fullscreen mode Exit fullscreen mode

but this will always be the bound object: {type: "bound"}.

Thread Thread
gauravshekhawat profile image
Gaurav-Shekhawat Author

thank you so much for your assistance