일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 회고록
- NEXT
- 이분 탐색
- 플로이드 와샬
- lazy propagation
- 분할 정복
- pytorch
- dropout
- 미래는_현재와_과거로
- c++
- 알고리즘
- 자바스크립트
- 우선 순위 큐
- 크루스칼
- 2023
- 다익스트라
- object detection
- 문자열
- BFS
- 백트래킹
- back propagation
- 가끔은_말로
- 세그먼트 트리
- dfs
- 가끔은 말로
- DP
- 조합론
- 너비 우선 탐색
- Overfitting
- tensorflow
- Today
- Total
Doby's Lab
[자바스크립트/JavaScript #1] first-class function, hoisting 될까 안 될까? 본문
자바스크립트 공부를 하다가 내 눈에는 이상한 점을 발견하여 포스팅을 하게 되었다.
const print = function () {
console.log('print');
};
print();
다음 코드를 실행하면 아무 문제없을 것이다.
허나,
print();
const print = function () {
console.log('print');
};
이 코드는 문제를 일으킨다.
[Uncaught ReferenceError: Cannot access 'print' before initialization]
해당 코드가 자바스크립트 엔진에서 돌아가는 원리는 다음과 같다.
//const는 재할당할 수 없지만 엔진의 설명을 위해
const print; //print라는 변수에 아무 것도 선언되지 않았다.
print(); //에러 발생
print = function () {
console.log('print');
};
즉, 변수 선언 자체는 hoisting이 되지만 변수에 선언된 내용은 hoisting이 되지 않은 것으로 볼 수 있다.
>> 함수(first-class function)를 call 하기 전에 함수는 선언이 되어있어야 한다.
다음 코드는 어떨까
function randomQuiz(answer, printYes, printNo){
if (answer === 'love you'){
printYes();
}
else{
printNo();
}
}
const printYes = function () {
console.log('yes!');
};
const printNo = function print() {
console.log('no!');
};
randomQuiz('wrong', printYes, printNo);
randomQuiz('love you', printYes, printNo);
randomQuiz라는 함수에서 printYes와 printNo라는 함수를
선언되기 전에 사용하고 있다. 그렇지만 에러가 나지 않는다.
왜 그럴까?
위 코드는 Call Back이라는 개념이 사용되어 그렇다.
(+수정)
----
코드 블록 안의 randomQuiz는 원래 function randomQuiz (answer) {... 와 같이 작성되었었다.
function randomQuiz (answer, printYes, printNo)로 수정하였다.
수정되기 전의 코드도 정상적으로 작동이 되지만
Call-Back을 공부하다 보니 '매개변수에 콜백을 할당한다'라는 개념을 벗어나
혼란이 왔었기 때문이다.
Call-Back function에 관한 내용은 아래에서 다뤘다.
----
맨 위에서 봤던 print함수는 print가 선언되기 전에 함수를 call 하여 에러가 발생한다. (2번째 코드 블록)
randomQuiz라는 함수는 어떠한 경우를 만족할 때, printYes나 printNo가 선언된 곳으로 찾아간다.
그래서 마지막에 randomQuiz라는 함수를 call 할 때, 3가지 함수가 다 선언되었으므로 에러가 나지 않는 것이다.
에러가 나는 경우는 아래와 같은 경우로 코드가 작성되었을 때 나타난다.
function randomQuiz(answer){
if (answer === 'love you'){
printYes();
}
else{
printNo();
}
}
randomQuiz('wrong', printYes, printNo);
randomQuiz('love you', printYes, printNo);
const printYes = function () {
console.log('yes!');
};
const printNo = function print() {
console.log('no!');
};
결론적으로 자바스크립트에서는 함수(first-class function)를 실행시키기 위해
해당하는 함수가 선언되어 있어야 하는 것이다.
first-class function은 변수에 함수를 할당하는 것이다.
변수를 선언할 때, 모든 변수가 hoisting 된다. 변수에 할당된 함수도 마찬가지다.
허나, 변수(first-class function)를 call 할 때 변수에 함수가 할당되어 있는지 확인하는 것이 이번 포스팅의 핵심이다.
마지막으로, 일반 function과 first-class function의 차이를 다음과 같이 확인할 수 있다.
//일반 function과 first-class function의 차이를 확인하기 위해
printThis();
function printThis(){
console.log(`this`);
}
//this를 출력함
//이유: function의 선언과 변수의 선언은 hoisting 되기 때문이다.
printThis2();
const printThis2 = function(){
console.log('this');
}
//this를 출력하지 않음
//변수 자체는 hoisting이 되었지만 함수 내용이 선언되지 않은 채 call을 했기 때문