6. Function Scope, Block Scope and Lexical Scope
19457 ワード
Articles
Functions
undefined
. Defining functions
Function Declaration
add(1,2) // 3
function add(value1, value2) {
console.log(value1 + value2);
return 1;
}
Function Expression
addNumber(2,3); // "ReferenceError: Cannot access 'addNumber' before initialization
const addNumber = function (value1, value2) {
console.log(value1 + value2);
return 1;
}
Arrow function
this
value const addNumber = (value1, value2) => {
console.log(this);
return this;
}
addNumber(2,3); // [object Window]
IIFE(Immediately invoked function expressions)
((value1, value2) => {
console.log(value1 + value2);
return 1;
})(2,3);
Scope
Scope defines what variable we can access to.
Global scope
Variables declared outside function, block are all contained in global scope.
POLE; Principle of least exposure
We should minimize the exposure of variables registered in each scope. It means that we should try our best to avoid delcaring variables in global scope. Why?
var
, the variable would shadow the previous value assigned. Second, with let
and const
, it would give error.Local scope
Function scope
var
is function scope. Precisely, Javascript had only function scope before ES6. It exists within the scope of function it's declared.const password = "3";
function checkIf(input) {
if(input == password) {
console.log(true);
}
else {
console.log(false);
}
}
console.log(password); // 3
checkIf(3); // true
Here, input
parameter is declared in function checkIf
scope. password
variable is declared in global scope which is very vulnerable. So, How can we hide the password
, still accessing to checkIf
function?function hidePassword() {
const password = "3";
return checkIf;
function checkIf(input) {
if(input == password) {
console.log(true);
}
else {
console.log(false);
}
}
}
console.log(password); // ReferenceError: password is not defined
const testCase = hidePassword();
testCase(3); // true
We hide the password
in hidePassword
function. As checkIf
function is inside the hidePassword
function and returned, we can access to this function.
const testCase =(()=>{
const password = "3";
return checkIf;
function checkIf(input) {
if(input == password) {
console.log(true);
}
else {
console.log(false);
}
}
})();
testCase(3); // true
By using IIFE, we can write it more clearer, shorter.Block scope
As
let
and const
introduced in ES6, both keywords are block scope. {}
becomes scope if it contains let
or const
.function add(value1, value2) {
{
let value3 = 4;
}
console.log(value3);
}
add(1,2); // "ReferenceError: value3 is not defined"
We have mentioned about POLE. So, it's best to put let
or const
declared variable in block scope as possible. What is Lexical scope?
JS program processes in two phases; Compilation & Execution.
In compilation, JS Engine parses through the code and checks which variables corresponds to which scope. This means that scope of variables are determined before execution, which we call it lexical scope.
For example,
let a = "3";
console.log(a); // SyntaxError: Unexpected token '.'
let b = ."4";
in this example, if there's no compilation phase, console.log(a)
should work fine. However, as the error was found before execution phase, it return error.Example
var name = 'zero';
function log() {
console.log(name);
}
function wrapper() {
var name = 'nero';
log();
}
wrapper(); // zero
function log
scope was determined before execution. It is nested in global scope, not wrapper
scope. So, as log
is executed as wrapper
is executed, first, engine looks at variable name
in funciton log
scope. As it is not declared in it, engine looks at outer scope, which is global scope. That's why it returns zero
.Reference
この問題について(6. Function Scope, Block Scope and Lexical Scope), 我々は、より多くの情報をここで見つけました https://velog.io/@gtfo/6.-Function-Scope-Block-Scope-and-Lexical-Scopeテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol