preface

JS foundation is very important for our front-end development. Therefore, we all choose to read some books to enrich ourselves. So when we read the rationale, are you still confused, or are you suddenly enlightened?

See through the appearance to the essence!

I thought: when you have a theoretical foundation to base it on, you should think about the results of the code and practice the theory.

Just like solving a bug, you always have to know the reason for the bug first, and then solve the problem according to the reason.

Code case

var b = 10;
(function b(){
    b = 20;
    console.log(b); }) ();Copy the code

What does this code output? (PS: Before you answer, think about it.)

At first glance, this code looks very simple and involves var Function IIFE, which seems to be fine.

TypeError: Assignment to constant variable TypeError: Assignment to constant variable

Type error: assignment to a constant variable

While in non-strict mode output:

Output analysis

  • Analyze the output in strict mode

TypeError: Assignment to constant variable To do an analysis, that means variable B is immutable!

The question now is whether variable B refers to the external variable b declared by var, or to the named function B that is executed immediately.

If b is a named function name that executes immediately, I’m honestly not sure it’s modifiable. (Ps: Most JS books don’t explicitly address whether a function expression can be reassigned when executed immediately.)

But I’m pretty sure that if B is declared externally with var, it must be modifiable in this code. We all know that a global variable declared with var must be modifiable anywhere, because the variable is at the top of the scope.

So I want to make a bold assumption here: the variable B refers to the named function name b~ that executes immediately

Having made this assumption, I’d like to say: does that mean that the global variable B is not accessible in the named function B that executes immediately?

The js engine will find the function declared variable b first when executing the code. The js engine will find the function declared variable B first when executing the code. As described in the book, scoped queries are performed from the inside out. (Ps: I also wrote a series of articles about scope: I understand JavaScript scope, hope to help you ~)

In non-strict mode, you can try printing window.b inside the immediate named function, or you can argue that the global variable B is accessible inside the immediate named function B! The code is as follows:

var b = 10;
(function b(){
    b = 20;
    console.log(window.b); }) ();Copy the code

Now that I’m clear about the internal scope mechanism for executing function B immediately, MY question arises: why can’t function expressions like (function b(){}()) be modified?

Later, I looked up the information, understand the internal mechanism of IIFE function ~

What I understand is: when encounter a named function expressions, will create a helper for specific objects, the name of the function expression as the only key, used to store the name of the function, and then added to the function of the scope chain, the value is read only, and can not be deleted, so can’t to this value.

TypeError: Assignment to constant variable. In strict mode, when a constant is modified, TypeError: Assignment to constant variable.

  • Analyze the output of the non-strict mode

Silent failure occurs in non-strict mode, so no errors are reported. After the above analysis, the named function b itself, which executes immediately, is printed.

Code extension

I rewrite the code as:

var b = 10;
(function b(){
	return 1; }) ();console.log(b); 
Copy the code

So what is this output going to be?

In both non-strict and strict mode, this code prints 10, which is the value of the global variable B ~

This code is not intended to be a guess, but rather to say: why is the immediate execution of named function B not externally accessible? Are all expressions externally inaccessible?

To solve my question, I use the following functions foo1 and foo2:

/ / section 1
var foo1 = function () {};
console.log(foo1);
/ / section 2
(function foo2(){})
console.log(foo2);
Copy the code
  • Fragment 1 assigns an anonymous function expression to the variable foo1, which can then be accessed using the name foo1 — foo1(). So printing is a function.
  • Fragment 2 is a functional expression, but the result isUncaught ReferenceError: foo2 is not defined. Note Is not accessible externally.

B is a function expression that cannot be accessed externally. Ps: means that a function expression cannot be called by name either before or after a function declaration.

In fact, code like section 1, described in most books and as I understood it earlier, is a function expression. But now my understanding is not so ~

Foo1 is a variable, and the anonymous function expression is assigned to the variable foo1, so foo1 is accessible!

By writing 2 code fragments, I solved my doubts ~

Think about other cases

In my spare time, I reformed the original code blocks, used these codes to review the past and thought about the theoretical basis of the previous study.

In the code snippet below, I will reveal the results as well, but I will also share my thoughts with you

  • Section 1
var b = 10;
function b() {
	console.log(12);
	return 1;
}
console.log(b, b()); //10 TypeError: b is not a function
Copy the code

Why do I print 10 instead of b?

Argument: function declarations take precedence over variable declarations ~

So, we declared function B with function and overwrote b with var.

/ / section 2
console.log(b, b()); / / 12 to 1
var b = 10;
function b() {
	console.log(12);
	return 1;
}
Copy the code

Why print the results 12 and 1 of function B instead of the global variable B?

Argument: function declarations take precedence over variable declarations and there is variable promotion in the process.

  • Section 3
var b = 10;
b = function() {
	b = 20;
	console.log(b); / / 20
return 1;
};
console.log(b, b()); / / b function, 1
Copy the code

Why do I print 10 instead of b?

Argument: The process is to reassign the variable B.

So instead of printing the function, it prints 10.

  • Section 4
var b = 10;
// Duplicate declaration "b"
let b = function() {
	b = 20;
	console.log(b);
	return 1;
};
Copy the code

Argument: Using var to declare variables can be repeatable, but using let to declare variables cannot be repeatable.

Var b = 10; let b = 10;

conclusion

When writing business code, try to avoid declaring variable name conflicts, because the above example is not written properly, and it is easy to have unexpected results.

Why not regulate yourself and avoid unnecessary trouble?

Of course, I think when learning boring and difficult theoretical basic knowledge, I think we should create our own imagination, practice more and think more about why there is such a result?

Prove the result according to theory!

This will enable me to understand the theoretical basis better and better use them, rather than just memorizing/memorizing.

The resources

JavaScript you Don’t Know (Part 1)

www.cnblogs.com/TomXu/archi…