function 함수명(){
구현 로직
}
// 예시
function funcDeclarations(){
return 'A function declaration';
}
funcDeclarations(); // 'A function declaration'
var 함수명 = function(){
구현 로직
}
//예시
var funcExpression = function(){
return 'A function expression';
}
funcExpression(); // 'A function expression'
// 실행 전
logMessage();
sumNumbers();
//
function logMessage() {
return 'worked';
}
var sumNumbers = function () {
return 10 + 20;
};
호이스팅에 의해 js해석기는 코드를 아래처럼 해석한다.
```javascript
// 실행 시
function logMessage() {
return 'worked';
}
var sumNumbers;
logMessage(); // 'worked'
sumNumbers(); // Uncaught TypeError: sumNumbers is not a function
sumNumbers = function () {
return 10 + 20;
};
실제 sumNumbers에 할당될 function 로직은 호출된 이후에 선언되므로, sumNumbers는 함수로 인식하지 않고 변수로 인식한다.
호이스팅을 제대로 모르더라도 함수와 변수를 가급적 코드 상단부에서 선언하면, 호이스팅으로 인한 스코프 꼬임 현상을 방지할 수 있다.
function tabsHandler(index) {
return function tabClickEvent(event) {
// 바깥 함수인 tabsHandler() 의 index 인자를 여기서 접근할 수 있다.
console.log(index); //탭을 클릭할 때 마다 해당 탭의 index 값을 표시
};
}
var tabs = document.querySelectorAll('.tab');
var i;
for (i = 0; i < tabs.length; i += 1) {
tabs[i].onclick = tabsHandler(i);
}
위 예제는 모든 .tab 요소에 클릭 이벤트를 추가하는 예제이다. 클로져를 이용해 tabClickEvent()에서 바깥 함수 tabHandler()의 인자 값 index를 접근했다는 점이다.
만약 클로져를 쓰지 않았다면 모든 tab의 index값이 for 반복문의 마지막 값인 tabs.length와 같다.
// 클로져를 사용하지 않았을 때
var tabs = document.querySelectorAll('.tab');
var i;
var logIndex = function (event) {
console.log(i); // 3
};
for (i = 0; i < tabs.length; i += 1) {
tabs[i].onclick = logIndex;
}
logIndex가 실행되는 시점은 이미 for문의 실행이 모두 끝난 시점이다. 따라서, 어느 탭을 눌러도 for문의 최종 값인 3이 찍힌다.
// doSth 라는 임시 변수를 사용
var doSth = function(){
};
$(document).ready(function(){
console.log('An anonymous function'); // 'An anonymous function'
});
var arr = ["a", "b", "c"];
arr.forEach(function () {
// ...
});
캡틴판교님의 블로그를 참고하였습니다.