1
2
3
4
5
6
7
8
9
var self = function() {
console.log('a');
return function () {
console.log('b');
}
}
self()(); // a // b
self = self(); // a
self(); // b
Let’s break this down step by step so it all makes sense. This code uses a combination of function expressions and closures, and we’re also reassigning the self variable along the way. Stick with me, and I’ll make it crystal clear.
Code Analysis
1
2
3
4
5
6
var self = function() {
console.log('a');
return function () {
console.log('b');
}
}
Initial Declaration
-
self** is assigned a function**:- When
selfis called, it:- Logs
'a'. - Returns another function (a closure) that logs
'b'.
- Logs
- When
Step-by-Step Execution
1. **self()();**
Let’s break it down:
-
self():- Calls the outer function.
- Logs
'a'. - Returns the inner function (
function () { console.log('b'); }).
- The returned function is immediately invoked by the second
():- Logs
'b'.
- Logs
Output so far:
```plain text a b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---
### **2. ****`self = self();`**
Let's dissect this:
1. `self()`:
- Calls the outer function again.
- Logs `'a'`.
- Returns the inner function.
2. `self = self()`:
- Assigns the returned inner function (`function () { console.log('b'); }`) to `self`.
**Output so far**:
```plain text
a
b
a
3. **self();**
Now, self has been reassigned to the inner function from the previous step.
- Calling
self():- Executes the inner function.
- Logs
'b'.
Final Output:
```plain text a b a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
---
### **Key Points to Understand**
1. **Outer Function (`self`)**:
- Logs `'a'` and returns the inner function.
2. **Inner Function**:
- Logs `'b'` when invoked.
3. **Reassignment of ****`self`**:
- After `self = self();`, `self` no longer points to the outer function. It now points to the returned inner function.
---
### **Visual Walkthrough of ****`self`**
1. **Initially**:
```javascript
self = function() {
console.log('a');
return function () {
console.log('b');
}
}
```
2. **After ****`self()();`**:
- `self()` logs `'a'` and returns the inner function, which logs `'b'`.
3. **After ****`self = self();`**:
- `self()` (outer function) logs `'a'` and assigns the inner function to `self`.
4. **After ****`self();`**:
- `self` now points to the inner function, so it logs `'b'`.
---
### **Full Output**
```plain text
a
b
a
b
Tips for Clarity
When debugging similar code:
- Trace what
selfpoints to after each step. - Understand that
self()changes based on its reassignment.
Got it now? Or need me to dig deeper? 😏
Exactly! You’ve got the concept down perfectly. Let me confirm and clarify each point for you so there’s no room for doubt.
1. Returning a Value vs. Returning a Function
When a function returns a value directly, you don’t need extra parentheses to access it. However, if the function returns another function, you need to invoke the returned function explicitly using ().
Returning a Value Example
1
2
3
4
5
6
7
var add = function(x, y) {
return x + y;
}
var result = add(2, 3); // Calls the function and gets the returned value
console.log(result); // Output: 5
- Here,
add(2, 3)directly returns a value (x + y), so you don’t need extra steps.
Returning a Function Example
1
2
3
4
5
6
7
var self = function() {
console.log('a');
return function () {
console.log('b');
}
}
2. Calling Outer and Inner Functions
Let’s break down your two scenarios.
Scenario 1: Calling Both Outer and Inner Functions
1
2
self()(); // First calls the outer function, then the returned inner function.
Step-by-step:
-
self():- Executes the outer function:
- Logs
'a'. - Returns the inner function.
- Logs
- Executes the outer function:
-
()(afterself()):- Immediately invokes the returned inner function:
- Logs
'b'.
- Logs
- Immediately invokes the returned inner function:
Output:
```plain text a b
1
2
3
4
5
6
7
8
---
### **Scenario 2: Calling Just the Inner Function**
```javascript
var func = self(); // Calls the outer function and assigns the returned inner function to `func`.
func(); // Invokes the inner function.
Step-by-step:
-
self():- Executes the outer function:
- Logs
'a'. - Returns the inner function, which is now stored in
func.
- Logs
- Executes the outer function:
-
func():- Invokes the inner function:
- Logs
'b'.
- Logs
- Invokes the inner function:
Output:
```plain text a b
```
Comparison
-
self()();:- Directly calls both the outer and the returned inner function in a single statement.
-
var func = self(); func();:- Calls the outer function, stores the returned inner function in a variable, then calls the inner function later.
Key Point
Whenever a function returns another function, you need to explicitly invoke the returned function with () if you want to execute it. If the function returns a direct value (like a number or a string), you just use it directly without extra parentheses.
You nailed it! Let me know if you want more examples or tricks to explore this further. 😏