Javascript Functions & Scope
- Functions 은 항상 값을 반환한다.
- return 값이 존재하지 않으면 undefined 를 반환한다.
- Functions 은 오브젝트이다.
- Scope 에는 두 가지 종류의 scope 가 존재한다.
- Global Scope
- Local Scope
Function Declaration & Function Expressions
- Function Declaration 은 이름에 기반한 함수로 정의된다.
- 함수는 선언되어 있기 때문에 순서에 상관없이 호출될 수 있다.
- Function Expressions 는 익명함수로 정의된다.
- "function" 구문으로 시작하지 않는다.
- 익명함수는 함수에 이름이 존재하지 않는다. 따라서 정의되기 이전까지 사용할 수 없다.
- 변수에 함수를 할당하는 형태이다.
named function Declaration
function say(){
console.log("Hello");
}
say(); // Hello
anonymous function Expression
let say = function(){
console.log("Hello");
}
say(); // Hello
anonymous function Expression (Error)
초기화 되기 전에 호출하면 스크립트 오류 발생
// Uncaught ReferenceError: Cannot access 'say' before initialization
say();
let say = function(){
console.log("Hello");
}
Self Invoking function Expression
// 즉시 실행된다.
(function say() {
console.log("Hello");
})();
anonymous function 의 아우터 및 이너 Error 발생코드
let number1 = 10;
let number2 = 20;
let calculate = function add(num1, num2){
return num1 + num2;
}
let valueOfOuter = calculate(number1, number2);
console.log(valueOfOuter); // 30
let valueOfInner = add(number1, number2);
console.log(valueOfInner); // Uncaught ReferenceError: add is not defined
- calculate() 에서의 함수호출은 무탈하게 호출되지만 내부적으로 add() 함수는 에러가 발생한다. 내부적으로 add() 함수를 이용하기 위해선 아래와 같이 사용해야 한다.
anonymous function 의 아우터 및 이너 변경사항
let number1 = 10;
let number2 = 10;
let calculate = function add(num1, num2){
if(num1 === num2){
return add(num1 + num2, num2);
}
return num1 + num2;
}
let value = calculate(number1, number2);
console.log(value); // 30
Arrow function
- function 키워드를 대신해서 화살표를 사용하여 간격하게 함수를 표현할 수 있다.
- this, arguments, super 등을 바인딩하지 않는다.
let say = () => {
console.log("Hello");
}
say(); // Hello
Parameters & Arguments
Parameters
- 일반적으로 함수를 작성하고 함수에 매개변수를 전달한다.
const param1 = "DOG";
const param2 = "CAT";
function twoParams(param1, param2){
console.log(param1 + ", " + param2);
}
twoParams(param1, param2); // DOG, CAT
/**
* param1 과 param2 를 파라미터라고 부른다.
*/
Arguments
- 매개변수를 통해 전달받은 함수 내 실질적인 값이다.
const param1 = "DOG";
const param2 = "CAT";
function twoParams(param1, param2){
console.log(param1 + ", " + param2);
}
twoParams(param1, param2); // DOG, CAT
/**
* DOG 와 CAT 이 아규먼트 즉 인수이다.
*/
Function Scope & Block Scope
- ECMA 6 (이하 es6) 가 나오기 이전에는 var 키워드를 통해서 변수를 선언하거나 초기화하였다.
- var 키워드는 변수의 영역이 모호하다.
function scope (var)
var name = "PARK";
function chanageName(){
var name = "KIM";
console.log("inner :", name);
}
chanageName();
console.log("outer :", name);
// inner : KIM
// outer : PARK
block scope : if statement (var)
/**
* var 키워드 사용
*/
var name = "PARK";
if(true){
/** if 조건문은 새로운 scope 를 생성하지 않는다. **/
var name = "KIM"; /** global scope **/
console.log("inner :", name);
}
console.log("outer :", name);
// inner : KIM
// outer : KIM
if 조건문에서 중괄호 "{}" 로 묶어놓은 영역 내의 변수 때문에 바깥의 값이 변함을 확인할 수 있다. 이러한 값의 변환은 개발자에게 혼란을 주기 충분하다. 위의 사례는 es6 부터 도입된 let 키워드로 해결할 수 있다.
block scope : if statement (let)
/**
* let 키워드 사용
*/
let name = "PARK";
if(true){
let name = "KIM"; /** local scope **/
console.log("inner :", name);
}
console.log("outer :", name);
// inner : KIM
// outer : PARK
let 을 통해 외부와 내부의 값이 따로 설정되는 것을 확인할 수 있다. 따라서 이전에는 function scope 로 이용되어왔다면 let 의 등장으로 block scope 가 가능하게 된 것이다.
loop
- 반복문 내에서 선언되는 초기값, 조건값, 증감연산자 등을 var 키워드 또는 let 키워드로 선언했을 때 결과값이 달리 나온다. 아래의 예시를 확인하자
var array = [];
for (var i = 0; i < 3; i++){
array.push(() => console.log(i));
}
array.forEach(f => f());
// 3 3 3
for (let i = 0; i < 3; i++){
array.push(() => console.log(i));
}
- 첫번째 코드는 3 3 3 이 찍힌다.
- 반복문은 scope 가 아니기 때문에 저렇게 값이 나타나는 것이다.
- 두번째 코드는 1 2 3 이 찍힌다.
정리
var 는 function scope 로 구분되기 때문에 값에 대한 동기화 문제가 발생한다. 반면에 let 은 block scope 인 중괄호에 의해서 구분되기 때문에 var 보다는 조금 더 엄격한 조건에서 값을 조작하는데 안전성이 있다.
reference
https://scotch.io/tutorials/understanding-scope-in-javascript#toc-introduction
'javascript > JS 33 Concepts' 카테고리의 다른 글
20190727 33-JS-Concepts :: 09 Message Queue & Event Loop (0) | 2019.07.27 |
---|---|
20190702 33-JS-Concepts :: 08 IIFE (0) | 2019.07.02 |
20190531 33-JS-Concepts :: 05 '===' & '==' 비교 (0) | 2019.05.31 |
20190526 33-JS-Concepts :: 04 Type Coercion (0) | 2019.05.26 |
20190525 33-JS-Concepts :: 03 Values Type & Reference Types (0) | 2019.05.25 |