자바스크립트 함수
목차
자바스크립트 함수에 대해서 기본을 알고 가겠습니다.
함수(Function)는 단어의 뜻 처럼 어떤 기능이라 볼 수 있습니다. 기계적으로 보면 특정 코드 블록까지 실행시키는 것. 인수를 받아서 지역변수에 매개변수를 생성하여 코드를 실행한 후 반환값을 호출자에게 보내는 것을 함수하고 합니다.
복잡해 보이지만 원리 자체는 간단합니다. 인수를 받아서 처리하고 돌려준다. 여기서 인수를 받아도 되고 안받아도 되고 반환값이 있어도 되고 없어도 됩니다.
예제를 통해서 알아보겠습니다.
함수 예제 – 매개변수와 반환값이 없다
function printHello() { console.log("Hello World of JS!"); } printHello();
function 키워드로 함수를 정의한 후 호출합니다. 콘솔창에 문자열을 출력합니다. 아주 단순하지만 이 log 가 앞으로 여러분들을 끝까지 도울 친구입니다.
console.log 도 함수입니다. 콘솔에 log 기록을 하기 위한 자바스크립트 내장함수인데요. 개발자들에게만 보이기 때문에 웹브라이저에서 무슨 일이 일어나고 있는지 추적할 수 있습니다. Chrome 에서 마우스 우클릭 – 검사를 하면 나오는게 바로 이 ‘개발자 모드’입니다.
웹브라우저기 때문에 누구나 볼 수는 있습니다. 그러나 무슨 의미인지 알수 없겠죠. 우리가 만든 printHello 함수는 다시 console.log 함수를 호출합니다. 함수란 것은 직접 만들 수도 있지만 거의 대부분은 남이 만들어 놓은 것, 정확히는 개발사가 제공하는 표준적인 함수들을 가져다 사용해서 응용 프로그램을 만드는 것 입니다.
앱 개발자들은 대부분 타인이 개발한 라이브러리를 가져다가 조합해서 새로운 앱을 개발하는 사람들입니다. 이 사실을 생각하면 초반 문법 공부가 지루하지 않습니다. 지금 배우는 모든 것들은 넘들이 만든 기술을 가져다가 쓰기위한 과정일 뿐입니다.
위 코드는 단순한 함수입니다. 매개변수가 없고 반환값이 없는 함수는 그 자체로 하는 일이 있는 함수입니다. 웹브라우저에 문자열을 표시한다. 그것만 가지고도 충분히 기능이 성립합니다. 함수가 종료하면 반환값을 돌려주지 않아도 제어권은 돌려줍니다. 거기까지가 함수가 할 일입니다.
함수 – 매개변수와 반환값 예제
일단 매개변수와 반환값이 있다는 것은 이 함수를 좀 더 유용하게 사용할 수 있다는 말입니다. 함수를 하나의 블랙박스로 보면 뭔가 숫자를 주면 답이 나옵니다. 그리고 나온 답을 가지고 새로운 연산을 할 수 있습니다. 답이 나왔는데 콘솔창에 출력만 하고 있으면 그 다음 연산이 진행이 안됩니다. 그래서 매개변수와 반환값은 연결된 겁니다.
매개변수를 가지고 수를 조작하여 반환값을 만들어 냅니다. 가장 단순한 예는 덧셈같은 사칙연산이고, 제곱, 세제곱, 루트 등 계산이 필요한 일이라면 다 해결할 수 있습니다.
아래는 예제입니다.
function myAdd(a, b) { return a + b; } var sum = myAdd(10, 9); console.log("result : " + sum); [실행값] result : 19
두개의 값을 받았습니다. a 와 b를 매개변수라고 합니다. 이들은 { } 함수의 지역변수입니다. 함수 바깥에서 사용할 수 없습니다.
return 으로 값을 돌려줍니다. 그 말인 즉슨 그 코드가 있는 줄에서 Lvalue(할당하는 값) 에다가 결과값을 대입합니다. 10 + 9 니까 19겠죠?
매우 간단한 예를 들었습니다. 그러나 매개변수에 전달할 수 있는 인수(Argument)에는 배열, 객체, 다차원 배열 등 제한이 없습니다. 반환값도 마찬가지 입니다. 숫자간의 덧셈은 쉬워보이는데 그럼 객체간의 덧셈은 어떻게 할까요? 배열간의 곱셈은? 이런 데이터 적인 부분을 해결해야 하는게 응용 프로그래머들이 고민할 부분입니다.
시중의 교재에는 사용자 입력을 받는 prompt 같은 함수나 출력하는 alert 함수로 예시를 많이 드는 것 같은데 학습적으로 크게 도움되는게 아니니까 넘어가겠습니다.
매개변수 – 동적 타이핑
자바스크립트를 동적 타이핑(dynamic tying) 언어라고 하는데 그 이유는 변수의 형을 사용자가 명시하는게 아니라 컴파일러(인터프리터)가 알아서 선택하기 때문입니다. 위에서 매개변수가 a, b 라고 했는데 이것만 보면 무슨 타입인지 알 수가 없습니다.
하지만 그게 또 자바스크립트의 장점이기도 합니다. 사용할 때 어떤 타입인지만 알 수 있다면 크게 문제가 되지 않습니다. 동적 타이핑에 반대적 언어는 정적 타이핑(static typing) 언어인 C나 자바 등이 있습니다. 이들은 a, b 로는 충분하지 않습니다. int a, int b 라던가 string a, string b 같이 명시해줘야 합니다.
이 둘은 반대적인 입장에 있는 언어의 특성을 잘 보여줍니다. 그러나 둘은 연결되어 있습니다. 원래 정적 타이핑 언어에서 컴파일러가 타입 오류를 잡아내기 위한 기술이 동적 타이핑으로 타입을 맞춰주는 기술로 진화한 것 입니다. 동적 VS 정적 이거는 타이핑 뿐 아니라 메모리 등에 걸려있는 주제인데 중급적인 주제를 다루기 위해서는 원리를 좀 알아야 합니다.
이론적 내용이지만 이렇게 함수에 적용되는 부분을 잘 보면 어느정도 답이 나옵니다.
변수의 범위(Scope)
함수를 다룰 때 변수의 범위에 대해서 한번은 언급하고 가는데요. 지역변수니 전역변수니 좀 어려운 주제지만 초반에 알아두면 좋습니다. 일단 구역에 대해서 { } 중괄호 안이 지역이라 식별합니다. 그런데 { { } } 와 같이 중첩되기도 하는데 이 때 { a { a } } 로 되있다면 바깥의 a와 안쪽의 a는 다릅니다.(let 사용)
안쪽에서 a를 찾으면 안쪽의 a를 우선적으로 사용합니다.
예제를 하나 보면 아래에서 함수에서 var 로 선언한 a는 가장 넓은 범위를 갖습니다. 아래 블록을 포함하죠. 함수안에서 { } 블록을 걸고 var 를 사용해도 역시 바깥에서 사용할 수 있습니다. 마지막 let은 그 블록을 떠나면 작동하지 않습니다.
그리고 함수의 블록을 떠나서 보면 a도 범위가 안잡히기 때문에 사용할 수 없습니다.
function scopeEx(){ var a = 999; console.log("t: " + a); { var c = 400; // let은 사용불가 let d = 300; // 블록 안에서만 사용가능 } console.log("c: " + c); } scopeEx(); // 범위가 없어서 사용불가 // console.log("a : " + a); [실행값] t: 999 c: 400
왜 이런 번거로운 일을 하는가? 범위를 좁힐 수록 코드의 안정성이 높아지기 때문입니다. 함수를 사용하는 stack 구조는 인접해서 데이터를 사용하기 때문에 메모리 효율이 좋고 빠른 전통의 자료구조입니다.
익명함수 (Anonymous Function)
익명함수는 이름이 없는 함수를 말합니다. 함수라는게 한번만 쓰고 말 것들도 많습니다. 이런 함수들을 다 거창하게 정의하고 만들어 놓는 것 보다 간단하게 변수에 저장해놓고 사용할 수 있습니다.
변수에 함수를 저장한다니 좀 이상하지만 결국 변수나 함수도 메모리 주소에 불과합니다. 변수에 함수가 시작하는 첫번째 코드를 주면 실행시키는게 가능합니다.
익명함수를 사용하면 딱딱한 프로그램을 유연하게 할 수 있는 장점도 있습니다.
var mySquare = function(x){ return x*x; } console.log("mySquare : " + mySquare(10)); console.log("mySquare : " + typeof mySquare); [실행값] mySquare : function mySquare : 100
또 하나의 익명함수는 매개변수를 미리 다 주고 계산을 시키는 방법입니다. 반환값을 typeof 로 조사하면 이미 계산이 끝나서 number 타입임을 알 수 있습니다.
var mySquare = (function(x){ return x*x; }(7)); console.log("mySquare : " + typeof mySquare); console.log("mySquare : " + mySquare); [실행값] mySquare : number mySquare : 49
화살표 표기법
익명함수에서는 화살표 표기법을 사용합니다. (ES6) function 키워드를 치는 것도 귀찮으니니까 이런 식으로 만들면 편리합니다. 문자열 다룰때는 ” ” ” 큰따옴표나 작은 따옴표가 아니라 ` <- 숫자 1옆에 있는 그레이브(Grave – 강세표)를 사용하는 부분에 주의하도록 합니다. ${변수} 이거는 변수를 문자열로 감싸는 거죠.
var myGreeting = () => `-- Hello mr.JS!`; console.log("*- type: " + typeof myGreeting); console.log(myGreeting()); var yourName = name => `-- Hello! ${name}`; console.log("*- type: " + typeof yourName); var myStr = yourName("Kim"); console.log(myStr); var myAdd = (num1, num2) => num1 + num2; console.log("myAdd: " + myAdd(15, 14));
기호로만 보면 복잡해 보이겠으나 막상 사용하기 시작하면 function 이렇게 치는게 손가락이 아프기 때문에 이게 좋아질 것 입니다. 물론 아직 기호 사용법에 익숙하지 않으면 function 으로 개념을 충분히 잡고 사용해도 늦지 않습니다.
중요한 것은 어떤 기호를 사용하는게 아니라 돌아가는 내용을 알아듣는게 우선입니다.
이벤트 처리 기본
자바스크립트는 이벤트 처리 기반의 언어입니다. 태생적으로 브라우저에서 작동하는게 목적이었기 때문에 이벤트 처리 기능이 내장되있습니다.
우리가 인터넷에서 무엇인가를 클릭하고 드래그 하고 키보드를 누르고 이 모든 일은 이벤트입니다. 단지 프로그래밍 관점에서 보면 브라우저는 항상 대기하고 있는 상태인 것입니다. 우리가 어떤 행동을 할 때 까지는 무한루프를 돌고 있다고 생각하면 됩니다.
그리고 어떤 이벤트라는 것은 이미 정해져 있습니다. 사용자가 입력할 수 있는 도구는 마우스, 키보드 등이 있습니다. 클릭이란 마우스의 전기적 신호로 운영체제가 하드웨어 인터럽트를 받아 그 이벤트의 목적인 프로세스(브라우저)에 값을 전달해 주는 과정을 발생시킵니다.
자바스크립트는 HTML 태그와 DOM 을 사용하여 이벤트 프로그래밍을 쉽게 구현할 수 있습니다. 물론 사용자 입장에서 쉽게 구현하는 것이지 내부적으로는 복잡한 로직이 깔려 있다는 것을 알 수 있습니다.
아래 예제를 보면 왜 자바스크립트가 웹의 핵심이 되는지 알 수 있습니다.
일단 버튼을 만들어두고요. 그 버튼 속성에 onclick을 설정합니다. onclick 은 클릭했을 때의 이벤트를 말합니다. 이밖에도 onmouseover 등 여러 이벤트가 일어납니다. 이벤트를 우리말로 하면 사건인데… 뭔가 말은 됩니다. 클릭 사건이 발생했다. 잘 쓰지는 않는 표현이죠? 그러나 컴퓨터의 세계에서는 맞는 말 입니다.
클릭 사건이 발생하면 그 사건을 low level 에서 high level 까지 전달하는 과정이 발생합니다. 최종적으로 우리는 웹브라우저에서 그 일이 일어나는 것을 보게됩니다. 중간 과정은 알필요 없죠. 더 많은 이벤트 종류에 대해서는 MDN 문서에서 찾아 볼 수 있습니다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="box1"></div> <div id="box2"></div> <input type="button" value="Button 1 - onclick" onclick="alert('clicked!')"/></br> <input type="button" value="Button 2 - onmouseover" onmouseover="alert('clicked!')"/></br> <input type="button" value="Button 3 - onclick - custom func" onclick="myEvent()"/></br> <input type="button" value="Button 4 - onclick - custom func" id="myBtn"/></br> <script src="scmain.js"></script> </body> </html>
count = 1; function myEvent () { console.log("button clicked! " + count); count++; } var myButton = document.querySelector("#myBtn"); myButton.onclick = function(){ console.log('clicked custom'); } myButton.onmouseover = () => { console.log('onmouseover custom'); }
html 을 DOM 객체로 잡아서 javascript 함수를 불러들이는 과정이 매우 직관적이기 때문에 함수를 몇개 만들어서 버튼에 붙여보면 어렵지 않을 겁니다.
버튼마다 지정할 수도 있지만 querySelector 로 해당 객체를 가져와서 각각 메소드를 오버라이드 하는 방법도 있습니다.
자바스크립트에서는 거의 대부분 이벤트 처리를 하는 것 인데요. 이벤트 종류와 처리방법이 워낙 다양하기 때문에 MDN 이나 깃허브에서 필요한 레퍼런스를 찾아서 응용하는 것이 좋습니다. 웹에다가 어떤 앱을 만들 것인가? 그게 정해지면 필요한 소스들을 모으는 일이 중요합니다.
요약
자바스크립트 함수 기본에 대하여 대강적으로 알아봤습니다.
원래 동적타이핑 언어들을 처음에 시작하면 static 언어 형식에 대한 개념이 없기 때문에 숫자는 숫자, 문자는 문자로 생각하며 코딩을 하게 됩니다. 뭐 그레 나쁜 것도 아니고 언어의 개발자들은 그것이 더 빠르고 효율적이라 생각한 것 입니다. 다만 항상 이야기 나오는게 일반 개발자들이 내부 사정을 점점 모르게 된다. 게다가 프레임워크가 매년 나오니까 더 알수 없게 됩니다.
그러다 보니 대화가 안통하는 시니어 개발자들이 컴퓨터 구조의 원리적인 부분을 자꾸 지적하게 됩니다. 자바스크립트도 타입스크립트와 더불어 바닐라 자바스크립트에 대한 중요성을 많이 강조하는 추세죠.
프로그래밍에 마스터라는 것도 없고 왕도도 없다고 합니다. 재능이 중요한 것도 사실이고 재능이 없는 사람도 훌륭한 앱을 개발할 수 있습니다. 케바케죠. 좀 옛날 사람들이 그 시대를 살다 보니 고집이 있어서 이분법적 논리를 강조하는데. 개인적으로 먹고사는 문제가 아니면 별로 중요하지 않다고 생각합니다. 그 이분법으로 나눈 내용에 생계가 영향을 받는다면 따르는게 좋습니다. 그게 아니라면 좀 free 한 영혼으로 돌아가서 코딩을 하는게 좋습니다.
코딩을 배운 다음에 free해지는게 아니라 코딩을 배우기 시작하면서 부터 free 해 지는 겁니다. 원래 막힌 사람들은 코딩을 다 배워도 갑자기 창조적으로 변하기 어렵습니다.
생각할 꺼리를 가지고 있는 것 그게 좋아서 이 웹사이트에 튜토리얼을 만들고 있는 것 이고요. 내용적으로는 부족할 수 있으니 항상 링크해두는 MDN 문서를 한번 더 읽고 참고하시길 바랍니다. 현재까지 자바스크립트 문서는 MDN 이 전세계 기준입니다.
이 세상에 한권의 교재로 얻을 수 있는 지식은 별로 많지 않습니다. 본인의 열정과 노력만이 제대로된 지식의 길로 인도할 뿐 입니다. 지식을 쌓는 것은 힘들지만 그 쌓아올린 지식을 넘어서거나 혹은 기존의 지식을 다 깨부수는 일은 보통 사람의 상상을 초월하는 일입니다.
많은 경우 사람들은 지식을 쌓다가 주어진 시간이 모자르거나 깜이 안되서 포기합니다. 하지만 처음부터 겁먹을 필요는 없습니다. 나이를 먹으며 몸은 느려져도 도전을 다짐하는 순간에 두뇌는 다시 처음 태어난 것 처럼 느끼기 때문입니다.
참고문서
Function – JavaScript | MDN (mozilla.org)
Introduction to events – Learn web development | MDN (mozilla.org)
좋은 글 감사합니다~
‘한 권의 교재로 얻을 수 있는 지식은 별로 많지 않습니다’ 라는 글귀가 되게 와닿네요 ㅎㅎ
독학으로 공부를 하다보니 생활코딩, 드림코딩 By 엘리, 프로그래머스, MDN 등 다양한 자료들을 참고하면서 공부하고 복습하는 과정 중에 이곳까지 흘러왔는데 개인적으로 초심자의 눈높이에 맞춰서 JS개념을 이해하기 좋게 정리를 잘 해주신 것 같아서 감명받고 갑니다!
안녕하세요, 방문과 좋은 말씀 감사합니다~
프로그래밍 독학으로 공부하기가 쉽지 않지만 생활코딩 등 좋은 자료들을 많이 보시니까 잘 하실거라 봅니다. 말씀하신 자료들은 저도 종종 참고합니다~