Scope is a very basic concept in JS. In ES5, there is only global scope and function scope. In ES6, block-level scope was added. But do you really understand scope?
Don’t rush to answer, first look at the following three questions. If you can’t do it or do it wrong, you don’t understand scope. If you do it right, you probably understand a third of scope, because there are still many concepts in it.
Subject to a
Please say the result of executing the following code separately:
console.log(fn)
function fn() {}
Copy the code
console.log(fn)
if(true) {
function fn() {}}Copy the code
console.log(fn)
if(false) {
function fn() {}}Copy the code
ES5 states that functions can only be declared in top-level scopes and function scopes, not block-level scopes. In ES6, however, functions are allowed to be declared in block-level scope, which has the following two features:
- Function names are promoted to global scope or header declarations of function scope (similar to var)
- The header declaration for the block-level scope in which the function body is promoted
As we all know, function promotion exists in ES5, but we need to pay attention to the difference between function declaration and function expression:
console.log(fnd) // [Function: fnd]
console.log(fne) // undefined
function fnd() {}
var fne = function() {}
Copy the code
As you can see, the function declaration elevates both the function name and the method body, while the function expression just elevates the function name. In ES6, if you define a function in a block-level scope, you only promote the function name, not the method body. The effect is equivalent to the function expression declared with var:
if(true) {
function fn(){} // equivalent to the following function expression
var fn = function(){}}Copy the code
[Function: fn], undefined, undefined
Topic 2
Say the result of executing the following code:
var x = 1, y = 1, z = 1
function func(x, y, f = () = >{x=2, y=2, z=2{})var x = 3
y = 3
z = 3
console.log(x, y, z)
f()
console.log(x, y, z)
}
func(4.4)
console.log(x, y, z)
Copy the code
In ES6, if a function sets a default value for an argument, the argument forms a separate scope when the function is declared initialized. So when the above code executes inside the function, it already has three scopes, which form the scope chain from bottom to top:
- Global scope
x=1,y=1,z=1
- Function parameter scope
x=4,y=4
- Function body scope
x=3
Var x=3; y=3; z=3; The result of the first print at this point is:
- X is the body scope and has a value of 3
- Y is the function parameter scope, and the value is 3
- Z is the global scope and has a value of 3
When f() is executed, it forms a new scope. Note that the upper scope of this function is not the func function body scope, but the func function parameter scope. This is because in JS the lexical scope is where functions are declared and defined in code, not where functions are executed. So after execution:
- X equals 2 changes x in the scope of the function argument
- Y equals 2 changes y in the scope of the function parameter
- Z =2 changes the global scope
And then when I print it again, it’s three, two, two. Finally, the function exits the stack, and since only z has been changed, it prints: 1, 1, 2. Final answer:
3, 3, 3, 2, 2, 1, 1, 2Copy the code
The title three
Say the result of executing the following code:
{} +0 ? console.log('yes') : console.log('no')
0+{} ? console.log('yes') : console.log('no')
Copy the code
This problem examines operator precedence, type conversions, and the ambiguity of {}. The ternary operators have lower precedence, so the left part of the question mark is computed first. The problem is that {} on the first line is not an empty object, but a block-level scope. {} on the second line is an empty object. So the first line is equivalent to:
{} +0 ? console.log('yes') : console.log('no')
Copy the code
So that’s kind of obvious. Print no. ValueOf () is not the original value. ToString () returns the string [object object], so 0+{} is 0. So the second line prints yes, and the final answer is:
no
yes
Copy the code