[함수] - 함수 선언 방법과 호이스팅

Donggu(oo)·2022년 11월 9일
0

JavaScript

목록 보기
15/49
post-thumbnail

1. 함수 선언 방법


1) 함수 선언문(Function declarations)

  • 함수 선언문은 function 키워드 옆에 함수명을 지정하여 함수를 선언하는 방식이다.
  • 호이스팅의 영향을 받는다.
  • 함수의 위치 상관없이 어디서나 호출이 가능하다.
// 함수 선언문
function sayHi() {
    console.log('Hi!');
}

// 함수 호출
sayHi();

// 선언 전에 호출되도 정상 동작
sayHi(); 

function sayHi() { 
    console.log('Hi!');
}

2) 함수 표현식(Function expression)

  • 함수 표현식은 정의한 function을 별도의 변수에 할당하는 것이다.
  • 함수 선언식의 경우 반드시 함수명이 정의되어 있어야 하지만, 함수 표현식은 없어도 되기 때문에(익명의 함수) 일반적으로 함수명을 정의하지 않는다.
  • 호이스팅의 영향을 받지 않는다.
// 함수 선언문
let sayHello = function () {
    console.log('Hello!');
}

// 함수 호출
sayHello();

3) 화살표 함수(Arrow function)

let getTriangleArea = (base, height) => {
  let triangleArea = (base * height) / 2;
  return triangleArea
}

2. 호이스팅(Hoisting)


호이스팅(Hoisting)이란?

  • 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말한다.
  • 일반적으로 선언되지 않은 변수는 접근할 수 없다. 마찬가지로, 자바스크립트에서도 선언되지 않은 변수를 접근할 수 없으며, 선언되지 않은 변수를 접근하면 Reference Error가 발생한다. 하지만 호이스팅 발생 시 나중에 선언되는 변수를 미리 접근할 수 있다.
  • 자바스크립트는 초기화가 아닌 선언만 호이스팅한다.

1) 변수 호이스팅

  • 사실 모든 변수 선언은 호이스팅이 발생한다. 그러나 letconst 키워드로 선언한 변수는 undefined로 초기화 되기 직전 TDZ에 머물게 되고 이때 변수를 참조하면 Reference Error가 발생하기 때문에 var 키워드로 선언한 변수만 호이스팅이 발생하는 것 처럼 보인다.
  • var 변수는 선언 단계와 초기화 단계가 동시에 진행된다. 즉, 자바스크립트 내부적으로 실행 컨텍스트의 변수 객체에 변수를 등록하는 동시에 undefined를 할당한다. 그렇기 때문에 변수에 값이 할당되기 전에 호출해도 Reference Error가 발생하지 않고 undefined가 반환된다.
  • var 변수/함수의 선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
console.log(name);  // undefined
var name = 'olaf';
var age = 27;

// var 변수에서 호이스팅 발생 결과
var name = undefined;
var age = undefined;
name = 'olaf'; // 후에 초기화가 이뤄짐
age = 27
console.log("hello");
var myname = "HEEE"; // var 변수 
let myname2 = "HEEE2"; // let 변수 

// var 변수에서 호이스팅 발생 결과
var myname; // [Hoisting] "선언"
console.log("hello");
myname = "HEEE"; // "할당"
let myname2 = "HEEE2"; // [Hoisting] 발생 X

2) 함수 호이스팅

2-1. 함수 선언문에서의 호이스팅

  • 함수 호이스팅이란 함수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 함수 호이스팅이라고 한다.
  • 함수 선언문으로 선언한 함수는 함수 선언문 이전에 호출(호이스팅)할 수 있다. 그러나 함수 표현식으로 선언한 함수는 함수 표현식 이전에 호출할 수 없다. 이는 함수 선언문으로 정의한 함수와 함수 표현식으로 정의한 함수의 생성 시점이 다르기 때문이다.
    - 함수 선언문은 코드가 한 줄씩 순차적으로 실행되는 시점인 런타임(runtime) 이전에 자바스크립트 엔진에 의해 먼저 실행(런타임 이전에 함수 객체 먼저 생성)된다. 그리고 자바스크립트 엔진은 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성하고 생성된 함수 객체를 할당한다.
  • 즉, 코드가 한 줄씩 순차적으로 실행되기 시작하는 런타임에는 이미 함수 객체가 생성되어 있고 함수 이름과 동일한 식별자에 할당까지 완료된 상태이다. 따라서 함수 선언문 이전에 함수를 참조할 수 있으며 호출할 수도 있다.

2-2. 함수 표현식에서의 호이스팅

  • 함수 표현식으로 함수를 정의하면 함수 호이스팅이 발생하는 것이 아니라 변수 호이스팅이 발생한다.
  • 함수 표현식의 변수 선언문 부분은 런타임 이전에 실행되어 undefined로 초기화되지만, 변수 할당문의 값은 할당문이 실행되는 시점, 즉 런타임에 평가되므로 함수 표현식의 함수도 할당문이 실행되는 시점에 평가되어 함수 객체가 된다.
  • 함수 표현식은 var로 선언됐을 경우 선언부만 호이스팅 된다.
// 함수 참조
console.log(add);  // add(x, y)
console.log(sub);  // undefined

// 함수 호출
console.log(add(2, 5));  // 7
console.log(sub(2, 5));  // TypeError: sub is not a function

// 함수 선언문
function add(x, y) {
  return x + y;
};
// 함수 표현식
var sub = function (x, y) {
  return x - y;
};

0개의 댓글