함수 선언문(declaration) / 표현식(expression) 의 차이 및 함수 표현식 내 일반 / 화살표 표기법

재우·2023년 8월 12일
0

함수 선언식 - Function Declareations

일반적인 프로그래밍 언어에서의 함수 선언과 비슷한 형식이다. 함수를 단순히 정의만 하고 실행하지는 않는 문장이라고 할 수 있다.

function sum(a,b){
	return a + b; // 일반함수
}

함수 표현식 - Function Expression

정의한 function을 별도의 변수에 할당하는 형식이다. 즉, 정의만 되는 함수 선언식과 달리 실행까지 포함하는 코드이며 동시에 코드실행 결과값을 특정 변수에 할당까지 한다.

var sum1 = function apple(a,b){
	return a + b; // 기명함수
}

var sum2 = function (a,b){
	return a + b; // 익명함수
}

함수 선언식과 함수 표현식의 차이 : 호이스팅

함수 선언식 = 함수 전체를 호이스팅
함수 표현식 = 변수 선언부만 호이스팅

ex.1)

  foo1();
  foo2();

  function foo1() { // 함수선언문
          console.log("hello");
  }
  var foo2 = function() { // 함수표현식
          console.log("hello2");
  }


  var foo2; // [Hoisting] 함수표현식의 변수

  function foo1() { // [Hoisting] 함수선언문
          console.log("hello");
  }

  foo1();
  foo2(); // ERROR!! 

  foo2 = function() { 
          console.log("hello2");
  }

ex2)

함수선언문에서의 호이스팅 : 함수선언문은 코드를 구현한 위치와 관계없이 자바스크립트의 특징인 호이스팅에 따라 브라우저가 자바스크립트를 해석할 때 맨 위로 끌어 올려진다.

/* 정상 출력 */
function printName(firstname) { // 함수선언문 
    var result = inner(); // "선언 및 할당"
    console.log(typeof inner); // > "function"
    console.log("name is " + result); // > "name is inner value"

    function inner() { // 함수선언문 
        return "inner value";
    }
}

printName(); // 함수 호출 

함수표현식에서의 호이스팅: 함수표현식은 함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 함수가 실행되지 않을 수 있다.
1. 함수표현식의 선언이 호출보다 위에 있는 경우 - 호이스팅과 상관없이 정상 출력

 /* 정상 */
 function printName(firstname) { // 함수선언문
     var inner = function() { // 함수표현식 
         return "inner value";
     }
        
     var result = inner(); // 함수 "호출"
     console.log("name is " + result);
 }

 printName(); // > "name is inner value"
  1. 함수표현식의 선언이 호출보다 아래에 있는 경우 (var 변수에 할당)
/* 오류 */
 function printName(firstname) { // 함수선언문
     console.log(inner); // > "undefined": 선언은 되어 있지만 값이 할당되어있지 않은 경우
     var result = inner(); // ERROR!!
     console.log("name is " + result);

     var inner = function() { // 함수표현식 
         return "inner value";
     }
 }
 printName(); // > TypeError: inner is not a function

Q. printName() 에서 “inner is not defined” 이라고 오류가 나오지 않고, “inner is not a function”이라는 TypeError가 나오는 이유?

A. printName이 실행되는 순간 (Hoisting에 의해) inner는 ‘undefined’으로 지정되기 때문이다. inner가 undefined라는 것은 즉, 아직은 함수로 인식이 되지 않고 있다는 것을 의미한다.


  1. 함수표현식의 선언이 호출보다 아래에 있는 경우 (const/let 변수에 할당)
/* 오류 */
 function printName(firstname) { // 함수선언문
     console.log(inner); // ERROR!!
     let result = inner();  
     console.log("name is " + result);

     let inner = function() { // 함수표현식 
         return "inner value";
     }
 }
 printName(); // > ReferenceError: inner is not defined

정리

  • 선언된 모든 함수들은 모두 Function 객체입니다. 그래서 Function 객체의 모든 속성 (property) , 메서드 및 행위 특성을 갖습니다.
  • Function Declaration 은 hoisting 되어 현재스코프의 최상단에서 선언됩니다. 때문에 선언 전에 사용 가능합니다.
  • Function Expression 은 variable에 함수를 저장하고 주로 이름이 없는 함수인 익명 함수를 사용합니다. hoisting되지 않아 선언 전에 사용 불가능 합니다.



~~ 그래서 어떤 방법을 더 선호하는가?
함수표현식보다는 함수선언식을 더 많이 사용한다고 한다.
함수 선언식을 이용하면, 함수가 선언되기 전에 호출이 가능하기 때문에 자유롭고 유연한 코드구성이 가능하다.
또한, 함수 선언식은 가독성이 좋다. 이는 ES6부터 등장한 화살표 함수(arrow function)와도 연관이 있다.
~~

함수 표현식 일반 / 화살표 표기법

case1. 매개변수가 없는 경우

// 일반 표기법
var introduce = function() {
    console.log("안녕하세요.");
}
introduce();

//화살표 표기법
var arrowIntroduce = () => console.log("안녕하세요.");
arrowIntroduce();


case2. 매개변수가 하나일 경우

// 일반 표기법
var introduce = function(name) {
    console.log("안녕하세요 제 이름은 "+ name +" 입니다.");
}
introduce("테디");

// 화살표 표기법
var arrowIntroduce = name => console.log("안녕하세요 제 이름은 "+ name +" 입니다.");
arrowIntroduce("테디");


case3. 매개변수가 2개 이상일 경우

// 일반 표기법
var introduce = function(name, age) {
    console.log("안녕하세요 제 이름은 " + name + "이고, 나이는 " + age + "세 입니다.");
}
introduce("테디", 18);

//화살표 표기법
var arrowIntroduce = (name, age) => console.log(
  "안녕하세요 제 이름은 " + name + "이고, 나이는 " + age + "세 입니다.");
arrowIntroduce("테디", 18);



일반적인 함수 표현식과 화살표 표기법의 차이

  • 간결함
  • this.

  1. 일반적인 함수 표현식보다 표현이 간결하다.
// 일반 표현식
var arr = [1, 2, 3];
var pow = arr.map(function (x) { // x는 요소값
  return x * x;
});

console.log(pow); // [ 1, 4, 9 ]
// 화살표 표기법
const arr = [1, 2, 3];
const pow = arr.map(x => x * x);

console.log(pow); // [ 1, 4, 9 ]
  1. this
    • 일반 함수표현식은 함수를 선언할 때 this. 에 바인딩할 객체가 정적으로 결정되는 것이 아니고, 함수를 호출할 때 함수가 어디서 호출되었는지에 따라 this. 에 바인딩할 객체가 동적으로 결정됩니다.
// 일반적인 함수 표현식
let param = 'global param';

let printParam = function() {
	console.log(this.param); // this = object
}

let object = {
	param: 'object param',
	func: printParam
}

object.func();      // object param
  • 화살표 함수는 함수를 선언할 때 this. 에 바인딩할 객체가 정적으로 결정되고, 동적으로 결정되는 함수 선언식과 달리 화살표 함수의 this. 는 언제나 상위 스코프의 this. 를 가리킵니다.
// 화살표 표기법
let param = 'global param';

let printParam = () => {
	console.log(this.param); // this = window
}

let object = {
	param: 'object param',
	func: printParam
}

object.func();    // global param


이처럼 호이스팅은 함수 선언문과 함수표현식에서 서로 다르게 동작하고 일반적인 함수표현식과 화살표표기법의 동작방식이 다르기 때문에 주의해서 함수를 사용해야한다.

0개의 댓글