function outer() {
const val = 1; // val is inside inner()'s closure
return function inner() {
console.log(val);
}
}
Closure is created when the following happens:
- A function
inner()
is created. - Inside
inner()
, some variable references to something out ofinner()
. Likeval
; - The referenced outer variable
val
becomes a closure variable and will always exist until no more referenced.
The funciton inner()
is called closure.
###1. Most Classical Question A common interview question starts like this:
const array = [];
for (var i=0; i < 10; i++) {
array[i] = function() {
console.log(i);
}
}
a[5](); // ?
The answer is 10
.
Because the function a[5]
references a variable i
which is outside. And the i
will be always there. Since all the i
referenced by a[0], a[1], a[2]... are the same outer one, all of them will be the same value: 10 (what the i became at the end).
const arr = [];
for (var i=0; i < 10; i++) {
arr[i] = function() {
i++;
console.log(i);
}
}
arr[5](); // ?
arr[6](); // ?
Yes, 11
and 12
will be logged. This proves same i
was shared and modified.
Then follow up will be: how do you fix it?
// Way 1: Use function:
const arr = [];
for (var i=0; i < 10; i++) {
arr[i] = (function(val) { // line-4
return function() {
console.log(val);
}
})(i); // pass i as innner function's val
}
arr[5](); // 5
arr[8](); // 8
As i is a primitive variable. We pass it by value. Means we are creating a copy and pass it into line-4
's function in every loop. No i is shared
now.
// Way 2: Use let
const arr = [];
for (let i=0; i < 10; i++) {
arr[i] = function() {
console.log(i);
}
}
arr[5](); // 5
arr[8](); // 8
This is one of the situation let
was created for.
For each loop, a new i
was created. And none of them is shared.
// Question 1
(function(x) {
return (function(y) {
console.log(x); // what will be logged?
})(2);
})(1);
// Question 2
(function(y){
return (function(y){
console.log(y); // what will be logged?
})(2);
})(1);
http://javascriptissexy.com/oop-in-javascript-what-you-need-to-know/ Create private variables:
// private in the regular functions
// private in constructors
function Student(id = 0, age = 20) {
var studentId = id;
this.age = age;
}
const stu1 = new Student(10192, 20);
stu1.studentId; // undefined
//
###References:
- 你应该知道的25道 Javascript 面试题