Home JavaScript - Function Call Expression
Post
Cancel

JavaScript - Function Call Expression

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

  1. self** is assigned a function**:
    • When self is called, it:
      • Logs 'a'.
      • Returns another function (a closure) that logs 'b'.

Step-by-Step Execution

1. **self()();**

Let’s break it down:

  1. self():
    • Calls the outer function.
    • Logs 'a'.
    • Returns the inner function (function () { console.log('b'); }).
  2. The returned function is immediately invoked by the second ():
    • Logs 'b'.

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.

  1. 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:

  1. Trace what self points to after each step.
  2. 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:

  1. self():
    • Executes the outer function:
      • Logs 'a'.
      • Returns the inner function.
  2. () (after self()):
    • Immediately invokes the returned inner function:
      • Logs 'b'.

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:

  1. self():
    • Executes the outer function:
      • Logs 'a'.
      • Returns the inner function, which is now stored in func.
  2. func():
    • Invokes the inner function:
      • Logs 'b'.

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. 😏

This post is licensed under CC BY 4.0 by the author.