[Javascript] C와 비교하며 학습하는 Javascript (4)
오늘의 학습자료 : 자바스크립트 12 - 함수(Function)
1.함수 호이스팅(Funciton Hoisting)
호이스팅(Hoisting)은 var 선언문, function 선언문 등 모든 선언문이 해당 범위(Scope)의 선두로 옮겨진 것 처럼 동작하는 특성을 말합니다. 소스코드 순서상 함수가 뒤에 있더라도, 변수값에 함수를 담을 수 있다는 것입니다.
이 방식이 가능한 이유는, C에서는 소스코드 순서대로 Compile되기 때문에 호이스팅 개념이 들어갈 수 없습니다. run 함수 내에 있는 call
함수 호출에 에러가 나는 부분을 참고하면 이를 알 수 있습니다.
JS에서는 스크립트가 로딩되는 시점에 바로 초기화하고 이를 VO(variable object)로 저장하기 때문입니다. 그래서 호이스팅 기능이 있는 경우, 아래 처럼 구현이 가능합니다.
var res = square(5);
function square(number) {
return number * number;
}
물론, 아래와 같은 예외도 있습니다.
var res = square(5); // TypeError: square is not a function
var square = function(number) {
return number * number;
}
만약 함수가 선언문
의 형식이 아니라, 표현식
일 경우, 스크립트 로딩시점이 아니라, Run-time 시점에 변수를 읽기 때문에 호이스팅되지 않습니다. 얼핏 보면 호이스팅 개념은 굉장히 편리한 부분처럼 보이지만... 인생사가 다 그렇듯이 편리하면 반드시 부작용이 있는 경우가 많네요. 🤔
Poiema 강의 내용 중,더글러스 클락포드
의 말을 인용하면 함수를 선언문으로 정의 시, 선언문이 많아지면 인퍼프리터가 너무 많은 코드를 Variable Object
에 저장하므로 속도가 느려지는 부분을 지적하기도 했죠.
2. 독특한 함수의 개념: 일급 객체, Return
일급객체의 특성은 다음과 같습니다.
- 무명의 리터럴로 표현이 가능
- 변수나 자료구조(객체, 배열 등)에 저장가능
- 함수의 매개변수에 전달 가능
- 반환값으로 사용 가능
// 1. 무명의 리터럴로 표현이 가능하다.
// 2. 변수나 자료 구조에 저장할 수 있다.
var increase = function (num) {
return ++num;
};
var decrease = function (num) {
return --num;
};
var predicates = { increase, decrease };
// 3. 함수의 매개변수에 전달할 수 있다.
// 4. 반환값으로 사용할 수 있다.
function makeCounter(predicate) {
var num = 0;
return function () {
num = predicate(num);
return num;
};
}
var increaser = makeCounter(predicates.increase);
console.log(increaser()); // 1
console.log(increaser()); // 2
var decreaser = makeCounter(predicates.decrease);
console.log(decreaser()); // -1
console.log(decreaser()); // -2
C를 처음으로 학습한 이후 보는 위의 코드는 매우 헷갈렸습니다. 단순히 절차대로 읽으면 이해하기 매우 까다롭네요..😵
호이스팅 및 함수가 매개변수로 들어가 있는 코드를 읽는 방식이 어려워, 나름대로 생각한 방법은 리턴값
에 집중하기. 입니다.
위 코드의 경우 predicate
에 담긴 값을 ++num, --num
으로 생각한 뒤에, makeCounter
함수는 어차피 호이스팅 되어있기 때문에, 건너뛰고, increaser, decreaser
에서 호출한 값이 무엇인지 보는 것이죠.
increaser
에는 predicates.increase
즉, ++num을 매개변수로 보냈고, makeCounter 내에 정의된 var num = 0
에 ++num처리를 해주라는 말로 이해할 수 있습니다. 위 코드가 간단해서 망정이지..여러번해서 숙달하는 법 밖엔!😏
리턴(Return) 의 경우에도, 특이한 녀석이 있습니다. 앞선 포스팅인 [포인터는 왜 배우는 것인가?][https://velog.io/@hw8129/CC-%ED%8F%AC%EC%9D%B8%ED%84%B0%EC%9D%98-%EC%82%AC%EC%9A%A9-21.03.23]에서 언급한 바가 있는데, C에서는 Return 값을 1개 이상 반환하지 못합니다. 이 때문에, 전역변수를 적극 활용하여, 함수 내에서 수정해주는 방식이 많습니다. 즉, 전역변수를 쓰냐 마냐도 C에서는 중요하게 고려해야할 사항입니다.
function getSize(width, height, depth) {
var area = width * height;
var volume = width * height * depth;
return [area, volume]; // 복수 값의 반환
}
console.log('area is ' + getSize(3, 2, 3)[0]); // area is 6
console.log('volume is ' + getSize(3, 2, 3)[1]); // volume is 18
JS에서는 return 값이 두 개가 가능합니다! 심지어 배열값 호출하는 것 마냥, getSize(3,2,3)[0]
과 같이 사용도 가능하죠. '엄격함'과 '엄격함이 주는 안락함' 그리고, '편리성, 자유로움'과 '편리성이 주는 부작용'. 일장일단은 프로그래밍에도 존재하는 진리인거 같습니다.
추후에는 함수 객체의 다양한 프로퍼티에 대해서 다뤄보려고 합니다.
Author And Source
이 문제에 관하여([Javascript] C와 비교하며 학습하는 Javascript (4)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@hw8129/Javascript-C와-비교하며-학습하는-Javascript-4저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)