자바스크립트에서 함수는 일급객체
입니다. 일급객체의 가장 큰 특성은 객체가 값으로써 변수에 할당될 수 있다
는 것 입니다.
자바스크립트의 일급객체 특성을 이용해서 이런 표현이 가능하겠습니다
이렇게 함수를 생성하고 변수에 값을 할당하는 것처럼 함수가 변수에 할당되었습니다. 함수는 특별한 종류의 값
이고, 따라서 변수에 할당할 수 있습니다.
여기서 단순히 1) sayHi
를 입력하면 괄호가 없기 때문에 함수는 실행되지 않습니다. 어떤 언어에서는 괄호가 없어도 함수가 실행되지만 자바스크립트에선 괄호가 있어야만
함수가 호출됩니다. 함수는 값이기 때문에 1)
을 실행시키면 함수 소스코드가 문자형으로 바뀌어 출력되는것을 볼 수 있습니다.
다음으로는 sayHi
를 새로운 변수 func
에 복사합니다. 이때 sayHi
다음에는 괄호가 없다는 점을 봐야합니다. 괄호가 있다면 sayHi
함수의 호출 결과가 func
에 저장되겠지만 괄호가 없으면 함수 그 자체가 저장되어 func()
로 함수를 호출할 수 있게 됩니다.
이러한 특징으로 인해 자바스크립트에서는 Callback함수
라는 것을 사용할 수 있습니다. 함수를 값처럼 전달하고, 전달 된 함수는 조건에 따라
실행될 수 있도록 만들어줍니다. 만약 여기서 괄호를 넣는다면
조건에 따라 실행되지 않고 바로 결과값이 넘어가겠죠?
함수 선언문과 함수 표현식은 변수에 선언 여부로 나타낼 수 있습니다.
sayBye
는 함수 선언문이고, 함수 표현식으로 만든 함수는 sayHi
변수에 할당된것을 볼 수 있습니다.
이 둘의 차이는 생김새 뿐만 아니라 자바스크립트 엔진
이 언제 함수를 생성하는지에 있습니다.
함수 선언문(function ...
)는 스크립트를 실행하기 전, JS엔진은 준비단계에서 전역에 선언된 함수 선언문들을 모두
찾고, 해당 함수를 생성합니다. 스크립트는 함수 선언문이 모두 처리된 이후에야 실행되는것입니다.
이러한 특징으로 함수 선언문은 함수 선언문이 정의되기 전에, 즉 함수를 먼저 코딩하고 그 아래에 함수를 코딩하여도 정상적으로 동작하는 이유입니다.
함수 표현식은 실제 JS엔진이 스크립트를 실행할 때, 코드를 한줄씩 읽다가 let sayHi = function...
부분을 읽을 때 함수가 생성됩니다. 이때부터 해당 함수(할당,호출 등)할 수 있는것입니다.
function sayHi() {
console.log("Hi");
sayHi.counter++;
}
sayHi.counter = 0;
sayHi();
sayHi();
console.log(sayHi.counter); // 2
위의 코드에서 함수에 counter
프로퍼티를 저장해보겠습니다. sayHi.counter = 0;
와 같이 함수에 프로퍼티를 할당해도 함수 내에 지역변수 counter
가 만들어지지 않습니다. counter
프로퍼티와 let counter
는 전혀 관계가 없습니다.
프로퍼티를 저장하는 것처럼 함수를 객체처럼 다룰 수 있지만, 이는 실행에 아무 영향을 끼치지 않습니다. 변수는 함수 프로퍼티가 아니고 함수 프로퍼티는 변수가 아니기 때문입니다.
둘 사이에는 공통점이 없습니다.
함수 프로퍼티를 사용하면 클로저를 대체할 수 있습니다. 클로저를 함수 프로퍼티로 대체하면 이제 클로저로 사용됐던 변수는 외부 렉시컬 환경
이 아닌 함수 프로퍼티에 바로 저장됩니다. 때문에 클로저
는 직접 접근이 불가능했던 반면 함수 프로퍼티로 사용하게 되면 값에 직접 접근이 가능해 집니다.
따라서 구현 방법은 외부에서 자유롭게 변경할지 아니면 접근이 불가능하게 사용할지에 따라 선택하면 될 것 같습니다.
- 함수는 값입니다. 따라서 함수도 값처럼 할당, 복사, 선언이 가능합니다.
함수 선언문
으로 함수를 생성하면, 함수가 독립된 구문 형태로 존재합니다.함수 선언문
은스크립트
시작 전엔 적역으로 선언한 선언문들이 처리 되고,코드 블록
이 실행되기 전엔 코드 블록 안에 있는 선언문들이 처리됩니다.함수 표현식
으로 함수를 생성하면, 함수가 표현식의 일부로 존재합니다.함수 표현식
은 실행 흐름이 표현식에 다다랐을 때 만들어집니다.