[JavaScript] 함수 표현식

Jin·2021년 10월 20일
0

JavaScript

목록 보기
6/12
post-thumbnail

1. 함수 표현식

자바스크립트는 함수를 다른 언어에서 "특별한 동작을 하는 구조"로 취급하는것과 달리, 특별한 종류의 값으로 취급한다.

// 함수 선언문 방식 //
function sayHi() {
  alert("Hello");
}

//함수 표현식//

let sayHi = function() {
  alert("Hello");
};

함수를 생성하고 변수에 값을 할당하는것처럼 함수가 변수에 할당되었다. 함수가 어떤 방식으로 만들어졌는지에 관계없이 함수는 값이고, 따라서 변수에 할당 할 수 있다.
위 예시를 간단히 말하자면 : "함수를 만들고 그 함수를 변수 sayHi에 할당하기
함수는 값이기 때문에 alert를 이용해 함수 코드로 출력 가능하다

function sayHi() {
    alert("Hello");
}

alert(sayHi);

위의 코드를 실행시키면 함수가 실행되지 않고 함수코드가 보이게 된다. 왜냐하면 sayHi뒤에 괄호를 입력하지 않았기 때문이다.

자바스크립트에서 함수는 값이다. 그렇기 때문에 변수를 복사해 다른 변수에 할당하는 것처럼 함수를 복사해 다른 변수에 할당할 수도 있다.

function sayHi(){
  alert("hello");
}

let func = sayHi; // 함수 복사

func(); // hello
sayhi(); // hello
  • 함수 표현식의 끝에는 왜 세미 콜론이 있을까?
    • if {...}, for{}, function f {} 같이 중괄호로 만든 코드 블록 끝엔 ; 가 없어도 된다.
    • 함수 표현식은 let sayHi= ...; 과 같은 구문 안에서 값의 역할을 한다. 코드 블록이 아니고 값처럼 취급되어 변수에 할당됨. 함수 표현식에 쓰인 세미콜론은 함수표현식 때문이 아니라, 구문의 끝이기 때문에 붙여졌다.

2. 콜백 함수

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no()
}

function showOk() {
  alert('동의했습니다');
}

function showCancel() {
  alert('Cancel');
}

// 사용법 : 함수 showOk와 showCancel이 ask함수의 매개변수로 전달됨
ask('동의하세요?',showOk,showCancel);

위와 같은 상황에서 함수 ask의 인수, showOkshowCancel 콜백 함수 또는 콜백 이라고 불린다.

함수를 함수의 인수(매개 변수)로 전달하고, 필요하다면 인수로 전달한 그 함수를 나중에 호출(called back) 하는것이 콜백 함수의 개념.

function ask(question, yes, no) {
  if (confirm(question)) yes()
  else no();
}

ask(
  "동의 하세요?",
  function() {alert("동의했습니다");}
  function() {alert("취소");}
);

위와 같이 이름 없이 선언한 함수를 익명 함수(anonymous function) 이라고 부른다.
익명 함수는 (변수에 할당 된거 아니기 때문에) ask 바깥에서는 접근 할 수 없다.

3. 함수 표현식 vs 함수 선언문

1) 문법

  • 함수 선언문 : 함수는 주요 코드 흐름 중간에 독자적인 구문 형태로 존재
  • 함수 표현식 : 함수는 표현식이나 구문 구성 내부에 생성. 아래 예시에서 함수가 할당 연산자 =를 이용해 할당 표현식 우측에 생성 됨
// 함수 선언문
function sum(a+b) {
  return a+b;
}

// 함수 표현식
let sum = function(a+b){
  return a+b;
}

2) 언제 함수를 생성하는지

  • 함수 표현식은 실제 실행 흐름이 해당 함수에 도달 했을 때 함수를 생성한다. 따라서 실행 흐름이 함수에 도달했을 대부터 해당 함수를 사용 할 수 있다.
  • 하지만 함수 선언문은 정의되기 전에도 호출 할 수 있다
    따라서 전역 함수 선언문은 스크립트 어디에 있냐에 상관없이 어디에서든 사용가능하다.
    그 이유는 자바스크립트 내부 알고리즘 때문이다. 자바스크립트는 스크립트를 실행하기 전, 준비단계에서 전역에 선언된 함수 선언문을 찾고, 해당함수를 생성한다. 즉, 스크립트가 실행되기전 "초기화 단계"에서 함수 선언 방식으로 정의한 함수가 생성되는 것.
sayHi("John"); // Hello, John

function sayHi(name) {
  alert(`Hello, ${name}`);
}

3) 스코프

  • 엄격모드에서 함수 선언문이 코드 블록 내에 위치하면 해당 함수는 블록 내 어디서든 접근 가능. 하지만 블록 밖에서는 접근 불가
let age = prompt('how old are you?', 18);

// 조건에 따라 함수 선언
if (age < 18) {
  function welcome() {
    alert('hi');
  }
} else {
  
  function welcome() {
    alert('Hello!');
  }
}

welcome(); // Error: welcome is not defined




또 다른 예시를 보자

let age = 16; // 16을 저장했다 가정합시다.

if (age < 18) {
  welcome();               // \   (실행)
                           //  |
  function welcome() {     //  |
    alert("안녕!");        //  |  함수 선언문은 함수가 선언된 블록 내
  }                        //  |  어디에서든 유효합니다
                           //  |
  welcome();               // /   (실행)

} else {

  function welcome() {
    alert("안녕하세요!");
  }
}

// 여기는 중괄호 밖이기 때문에
// 중괄호 안에서 선언한 함수 선언문은 호출할 수 없습니다.

welcome(); // Error: welcome is not defined

if문 밖에서 welcome 함수를 호출하는 방법은?

let age = prompt('how old are you?', 18);
let welcome;

if (age < 18) {
  function welcome() {
    alert('hi');
  };
} else {
  
  function welcome() {
    alert('Hello!');
  };
}

welcome(); // 제대로 동작

물음표 연산자를 사용하면 좀 더 단순화 가능하다.

let age = prompt('how old are you?', 18);

let welcome = (age < 18) ?
    function() { alert('hi'); } :
    function() { alert('Hello!'); };

welcome(); // 제대로 동작

4. 둘 중 무엇을 선택해야 할까?

함수 선언문을 이용해 함수를 선언하는 걸 먼저 고려하는게 좋다. 함수 선언문으로 함수를 정의하면, 함수가 선언되기 전에 호출을 할 수 있어 코드 구성을 좀 더 자유롭게 할 수 있기 때문이다.
또한 가독성도 좋아진다.
하지만 꼭 선언문을 사용하라는것은 아니다. 함수 선언 방식이 적합하지 않거나, 조건에 따라 함수를 선언해야 한다면 함수 표현식을 사용해야 한다.

자료 출처 : https://ko.javascript.info

profile
내가 다시 볼려고 작성하는 블로그. 아직 열심히 공부중입니다 잘못된 내용이 있으면 댓글로 지적 부탁드립니다.

0개의 댓글