< 함수 >
:: 특정 작업을 수행하는 각 코드를 하나로 묶어 놓은 것
:: 자바스크립트에서 함수는 객체
:: 모든 함수는 Function 타입의 인스턴스로 다른 참조 타입과 마찬가지로 프로퍼티와 메서드가 있다.
* 함수 정의
:: 함수의 생성방법 3가지가 존재
- 함수 선언문(function statement)
- 함수 표현식(function expression)
- Function() 생성자 함수
* 함수 리터럴
:: 객체 리터럴, 배열 리터럴 방식으로 생성할 수 있는 것처럼 자바스크립트 함수도 함수 리터럴을 이용해 함수 생성 가능
:: 함수 선언문이나 함수 표현식 방법 모두 이런 함수 리터럴 방식으로 함수를 생성
- 함수 선언문 방식으로 함수 생성
:: 함수 선언문 방식은 함수 리터럴 형태와 같다
:: 함수명이 반드시 정의되어 있어야 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function 함수명([parameter1, parameter2,...]){ //.... } :: 함수를 선언할 때 function키워드 사용 :: 함수 선언부에 함수의 리턴타입은 명시하지 않음 :: parameter를 사용하지 않으면 괄호 안을 비운다 :: 함수를 <body>태그 내에서 호출할 때 <script>~</script>내에 하도록 한다. :: parameter를 선언할 때 var 키워드를 사용하지 않는다. :: 함수에서 값 전달 방식은 passing by value 방식을 취한다. :: 페이지의 head에 모든 함수를 정의하는 것이 일반적이고, 이는 페이지가 읽혀질 때 이 함수들이 먼저 읽혀짐 :: 함수에서 문장은 현재 페이지에서 정의한 다른 함수를 호출할 수도 있다. :: 함수는 재귀 호출, 즉 자기 자신을 호출할 수 있다. :: return 문을 만나면 자바스크립트 코드는 더 이상 수행되지 않는다. // a() 함수 선언문 function a(x,y){ return x + y; } console.log(a(10,20));
|
|
- 함수 표현식 방식으로 함수 생성
:: 자바스크립트는 함수도 하나의 값으로 취급
:: 함수도 숫자나 문자열 변수에 저장하는 것이 가능
:: 함수 리터럴로 하나의 함수를 만들고 여기서 생성된 함수를 변수에 저장하여 함수를 생성하는 것을 함수 표현식이라고 한다.
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 32 33 34 35 36 37 38 39 40 41 | 함수명 = function([parameter1, parameter2,...]){ //.... } // a() 함수 표현식 var a = function(x,y) { //익명함수 return x + y; }; var p = a; console.log(a(1,2)); // 3 console.log(p(1,2)); // 3 :: 함수 표현식 방법에서 함수 이름이 선택 사항이며, 함수 이름이 없으면 익명 함수라고 한다. 이를 익명함수를 이용한 함수 표현식 방법이라고 한다 :: 함수 이름이 포함된 함수 표현식은 기명 함수 표현식이라고 한다. // 기명함수 표현식 var a = function sum(x,y){ return x + y; } console.log(a(1,2)); console.log(sum(1,2)); //error: sum is not defined :: sum()함수를 정의하고 a함수 변수에 저장. :: 함수 표현식에서 사용된 함수 이름은 외부 코드에서 접근이 불가능하기 때문에 error 발생 :: 사용된 함수 이름은 정의된 함수 내부에서 해당 함수를 재귀적으로 호출하거나 디버거 등에서 함수를 구분할 때 사용 // 기명함수 표현식을 이용한 재귀적 호출 // 팩토리얼 함수 var fact = function factorial(n) { if(n <= 1){ return 1; } else { return n * factorial(n-1); } }; console.log(fact(4)); //24 |
|
- Function() 생성자 함수를 통한 함수 생성
:: 자바스크립트 함수도 Function()이라는 기본 내장 생성자 함수로부터 생성된 객체다
:: 함수 선언문,함수 표현식 방식은 함수 리터럴 방식으로 함수를 생성하지만, 내부적으로는
Function() 생성자 함수로 함수가 생성됨
| // Function() 생성자 함수를 이용한 a()함수 생성 var a = Function('x','y','return x+y'); console.log(a(1,2)); //3 :: 하지만 function() 생성자 함수를 이용한 방식은 잘 쓰이지 않음 |
|
* 함수 호이스팅(hoisting)
:: 함수 선언문에서의 함수 호이스팅
:: 함수가 정의되지 않은 시점에서도 정의되기 이전의 함수를 호출하는 것이 가능
:: 함수가 자신이 위치한 코드에 상관없이 함수 선언문 형태로 정의한 함수의 유효범위는 코드의 맨 처음부터 시작
| console.log(plus(1,1)); //2 function plus(a,b){ return a + b; } :: 함수 표현식 형태로 정의되어 있으면 호이스팅이 일어나지 않는다. console.log(plus(1,1)); // uncaught type error! // 함수 표현식 방식 var plus = function(a,b){ return a+b; } console.log(plus(1,1)); |
|
* 함수 객체의 기본 프로퍼티
- name
:: 자바스크립트 함수의 name 프로퍼티는 함수의 이름을 나타냄
- caller
:: 자바스크립트 함수의 caller 프로퍼티는 자신을 호출한 함수를 나타냄
- arguments
:: 자바스크립트 arguments 프로퍼티는 함수를 호출할 때 전달된 인자 값을 나타냄
| function list(){ for(var i = 0; i < list.arguments.length; i++) document.write("<li>"+list.arguments([i]); } list(1, "경기도","서울",3); :: length 프로퍼티는 함수가 넘겨받을 것으로 예상하는 이름 붙은 매개변수의 숫자로 함수가 정상적으로 실행될 때 기대되는 인자의 개수를 나타냄 |
|
* 자바스크립트 함수의 다양한 종류
- 콜백 함수
:: 익명 함수의 대표적인 용도가 콜백 함수
:: 코드를 통해 명시적으로 호출하는 코드가 아니라, 개발자는 함수를 등록하기만 하고 어떤 이벤트가 발생하거나 특정 시점에
도달했을 때 시스템에서 자동으로 호출되는 함수를 말한다.
:: 특정 인자(매개변수)로 너겨서 코드 내부에서 호출되는 함수도 콜백 함수
:: 대표적 사용 예가 @이벤트 핸들러 처리
| // 페이지 로드 시 호출될 콜백 함수 window.onload = function(){ alert("안녕하세요"); } :: 웹페이지가 로드 되거나 마우스가 클릭되는 등의 DOM 이벤트가 발생한 경우 브라우저는 정의된 DOM 이벤트에 해당하는 이벤트 핸들러를 실행 시킨다. :: 이벤트 핸들러에 콜백 함수가 등록돼있다면 콜백 함수는 이벤트가 발생할 때마다 브라우저에 의해 |
|
- 즉시 실행 함수
:: 함수를 정의함과 동시에 바로 실행하는 함수
| (function(name){ console.log(name) })('test'); //test출력 :: 함수 리터럴을 괄호()로 둘러싸준 다음 함수가 바로 호출될 수 있게 ()을 추가해주어 만든다 :: 괄호 안에 값을 추가해주면 즉시 실행 함수의 인자(매개변수)로 바로 넘길 수 있다. :: 최초 한 번의 실행만을 필요로 하는 초기화 코드 부분에 자주 사용됨 |
|
- 내부 함수
:: 자바스크립트에서는 함수 코드 내부에서도 다시 함수 정의가 가능
:: 함수 내부에 정의된 함수를 내부함수라고 한다.
:: 기능을 보다 강력하게 해주는 클로저를 생성하거나, 부모 함수 코드에서 외부에서의 접근을 막고
독립적인 헬퍼 함수를 구현하는 용도 등으로 사용
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // parent() 함수 정의 function parent(){ var name = '엄마'; var age = 50; // child()함수 정의 function child(){ var name = '나'; console.log(name); console.log(age); } // parent()함수에서 child()함수 호출 child(); } parent(); child(); //오류 :: child() 내부 함수에서는 변수 age가 선언되지 않아도 child()함수가 호출됐을 때 값이 출력된다. :: 변수 name은 child() 함수에 선언이 되어 있어 parent() 함수의 변수 name이 아닌 child() 함수의 변수 name의 값이 출력됨 :: 이게 가능한 이유는 자바스크립트의 스코프 체이닝 때문.
|
|
- 함수를 리턴하는 함수
:: 자바스크립트에서는 함수도 객체이므로 일반 값처럼 함수 자체를 리턴할 수 있다.
| function a() { console.log("animal"); return function(){ console.log("tiger"); } } var zoo = a(); // 출력값 "animal" zoo(); // 출력값 "tiger" |
|
* 자바스크립트 클로저
:: 자신의 범위(scope) 밖에 있는 변수들에 접근할 수 있는 함수
:: 자바스크립트의 모든 함수들은 클로저
- 클로저
:: 범위에 제약을 받지 않는 변수들을 포함하고 있는 코드블록이다. 이런 변수들은 코드 블록이나 글로벌 컨텍스트에서
정의되지 않고 코드 블록이 정의된 환경에서 정의된다.
:: 실행할 코드블록(자유 변수의 관점에서 변수 레퍼런스와 관련하여 폐쇄적이지 않는)과 자유변수들에 대한 바인딩을 제공하는 평가 환경(범위)의 결합에서 탄생
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | var sequencer = function() { var s = 0; return function(){ return ++s; } }; /* seq 함수는 이런 구조를 가지고 반환될 것 function seq(){ return ++s; } */ seq(); // 1 seq(); // 2 seq(); // 3 :: 보통 언어의 seq() 결과는 모두 1 이지만 자바스크립트는 다른다 :: 이미 sequencer 내부의 s변수는 다른 언어에서는 유효범위를 벗어난 쓸 수 없는 변수로 자바 같은 가비지 컬렉터를 가진 언어에서는 가비지 컬렉팅의 대상이 된다. :: 자신이 선언된 환경에 대해 연결을 갖고 예제에서 반환된 함수는 자신이 선언될 때의 환경인 sequencer의 유효범위에 대한 연결을 갖게 되고, ㅗ출하게 되면 그 연결을 통해 s 변수에 "직접" 접근한다. 하지만, 변수를 복사 하는게 아니라 변수가 있는 객체를 참조하는 것. :: s변수를 복사했다면 반환되는 값은 항상 1 이어야 한다. // 모든 li 태그를 클릭할 때 자신의 순번을 표시하는 예제 var items = document.getElementsByTagName("li"); for(var i=0; i<items.length; i++){ items[i].onclick = function(event){ alert("My Sequence is " + (i+1)); //자신의 순번 출력 } } :: 여기서 우리가 기대한 ㅏㅄ은 li태그를 클릭할 때 자신이 문서에 사용된 순서를 출력하는것 :: 여기서 출력하는 값은 li의 제일 마지막 순번의 값에 1을 더한 값만이 출력된다. :: 값이 복사된 것이 아닌 변수에 직접 접근하고 있기 때문 :: for문이 종료되는 시점의 i값은 4 이며, 핸들러는 그것에 직접 접근하여 1을 더한 값만을 출력하게 되는 것 // 위의 함수가 제대로 동작하도록 수정 var items = document.getElementsByTagName("li"); for( var i = 0; i < items.length; i++){ (function() { //새로운 스코프 선언 var idx = i; //클로저가 접근할 변수 선언 items[i].onclick = function(event){ alert("My Sequence is " + (idx+1)); } })(); //함수 생성과 동시에 호출(즉시 실행 함수) } :: 이벤트 함수인 클로저가 참조하는 대상이 i가 아닌 새로운 스코프의 idx가 되었다. :: 막강한 문법이긴 하지만 주의할 점이 있는데, 함수가 메서드로 호출될 때 외부 함수의 this 키워드와 특수한 변수인 arguments에 는 정상적인 접근이 되지 않는다. 정확하게는 저 둘에 대해서는 메서드를 소유한 객체의 this에 연결되지 못한다. // 아래 코드를 보면 window.name = "window"; var object ={ name:"object", getName: function(){ function findName(){ return "my name is " + this.name; } return findName(); } } object.getName(); // my name is window :: 위의 코드는 의도와는 다른 동작을 보인다. :: my name is object가 아닌 my name is window가 출력된다. :: 메서드 내부의 함수가 실행될 때 this가 메서드를 소유한 객체에 연결된 것이 아닌, 글로벌 객체에 연결되었기 때문. // 따라서 위 코드에서 getName 부부을 수정한다. window.name = "window"; var object ={ name:"object", getName: function(){ var that = "this"; // this를 따로 변수에 할당해둬 내부 함수가 접근 가능하도록 한다. function findName(){ return "my name is " + that.name; } return findName(); } }
|
* 자바스크립트 내장 함수
:: 자바스크립트 자체적으로 제공되는 함수
- 타이머 함수
:: 특정한 시간에 특정한 함수를 실행
-) setTimeout(function, millisecond)
::일정 시간 후 함수를 한 번 실행
-) setInterval(function, millisecond)
:: 일정 시간마다 함수를 반복 실행
-) clearTimeout(id)
:: 일정 시간 후 함수를 한 번 실행하는 것을 중지
-) clearInterval(id)
:: 일정 시간마다 함수를 반복하는 것을 중단
- 인코딩과 디코딩 함수
1) 인코딩
:: 문자를 컴퓨터에 저장 또는 통신에 사용할 목적으로 부호화하는 방법
2) 디코딩
:: 부호화 된 문자를 원래대로 되돌리는 것
-) escape()
:: 영문 알파벳과 숫자,일부 특수문자(@,*,-,_,+,.,/)를 제외 문자만 인코딩
-) unescape()
:: 영문 알파벳,숫자,일부 특수문자(@,*,-,_,+,.,/)를 제외 문자만 디코딩
-) encodeURI(uri)
:: 인터넷 주소에 사용되는 일부 특수문자(:, ;, /, =, ?, &)를 제외 문자만 인코딩
-) decodeURI(encodedURI)
:: 인터넷 주소에 사용되는 일부 특수문자(:, ;, /, =, ?, &)를 제외 문자만 디코딩
-) encodeURIComponent(uriComponent)
:: 알파벳과 숫자를 제외한 모든 문자를 모두 인코딩
-) decodeURIComponent(encodedURI)
:: 알파벳과 숫자를 제외한 모든 문자를 모두 디코딩
- 코드 실행 함수
:: 문자열을 코드로 실행 할 수 있는 특별한 함수
:: eval() 함수로 실행 된 코드에서 정의한 변수도 활용 가능
-) eval(string)
:: string을 자바스크립트 코드로 실행
- 숫자 확인 함수
:: 변수에 숫자가 무한한지, number인지 확인
-) isFinite()
:: number가 무한한 값인지 확인, 유한한 수이면 true를 리턴
-) isNaN()
:: number가 숫자인지 확인, 숫자가 아니면 true를 리턴
- 숫자 변환 함수
:: Number() 함수의 단점(숫자로 바꿀 수 없으면 NaN으로 변환)을 보완한 숫자 변환 함수 제공
:: parseInt() 함수와 parseFloat() 함수는 앞에서부터 숫자로 변환할 수 있는 부분까지는 모두 숫자로 변환
:: 0으로 시작하거나 0x로 시작하면 10진수가 아니라 8진수, 16진수로 생각하고 변환
:: parseInt() 함수의 두 번째 매개변수에 진법을 입력하면 앞의 수를 해당 진법의 수로 인식
-) parseInt(string)
:: string을 정수로 변환
-) parseFloat(string)
:: string을 소수로 변환
* 자바스크립트 경고창 및 입력
- alert() 메서드
:: 사용자에게 필요한 정보를 디스플레이 하는 독립된 메시지 윈도우를 만들며 ok버튼만 존재하는 모달 대화상자.
| alert("message") // message는 텍스트 문자열 |
|
- prompt() 메서드
:: 문자열을 입력할 때 사용
| String prompt([String message], [String defaultValue]) :: 첫 번째 매개변수는 입력 창에서 띄워줄 메시지 :: 두 번째 매개변수는 입력 부분의 기본 값 |
|
- confirm() 메서드
:: boolean 값을 입력 받을 때 사용
:: 확인을 누르면 true를 리턴
:: 취소를 누르면 false를 리턴
| var input = confirm('작성하시겠습니까'); alert(input); |
|
* 예외 처리(Exception handling)
:: 프로그램이 실행되는 동안 문제가 발생할 때 대처할 수 있게 처리하는 것
- 예외(Exception)
:: 프로그램 실행 중 발생하는 오류
- 에러(Error)
:: 프로그래밍 언어의 문법적인 오류
- 예외 처리
:: try 키워드, catch 키워드, finally 키워드로 예외 처리
:: try 구문 안에서 예외가 발생하면 catch 구문에서 처리, finally 구문은 필수 사항은 아니고 예외 발생
여부와 상관없이 수행돼야 하는 작업을 처리
| try{ // tryCode; } catch(e){ // catchCode; } finally{ //finallyCode; } |
|
- 예외 객체
:: try~catch 구문을 사용할 때 catch 괄호 안에 입력하는 식별자
:: e 또는 exception 식별자를 사용
:
-) 예외 객체의 속성
:: message = 예외 매시지
:: description = 예외 설명
:: name = 예외 이름
- 예외 강제 발생
:: 예외를 강제로 발생시키는 throw 키워드 사용
:: 에러와 다르게 예외는 try~catch 구문으로 처리할 수 있다.
* 동적 HTML 관련 함수 및 속성(JavaScript HTML DOM - Changing HTML)
- object.getElemantsByName(elementid)
:: id 애트리뷰트 값에 맞는 처음 객체를 반환
- object.getElementsByName(name)
:: name 애트리뷰트의 값에 기초하여 객체들의 컬렉션을 반환
- document.write(text)
:: HTML 출력 스트림에 직접 출력
- object.innerHTML
:: innerHTML 속성을 지원하는 객체의 시작 태그와 종료 태그 사이에 있는 HTML을 설정하거나 가지오 올 수가 있다.
:: innerHTML 속성은 해당 웹 문서를 완전히 읽어들인 후(onload 이벤트 발생 후)에 사용할 수 있다.
:: innerHTML, innerText, outerHTML, outerText 속성은 <table>,<td>,<div>,<span>,<p> 등에서만 사용 가능하고
<input>,<img> 태그에서는 사용할 수 없다.
- object.innerText
:: innerText 속성을 지원하는 객체의 시작 태그와 종료 태그 사이에 있는 텍스트를 설정하거나 가지고 올 수 있다.
:: HTML 태그를 삽입하여도 태그 자체를 텍스트로 인식
- object.outerHTML
:: 해당 텍스트를 포함하고 있는 태그 요소까지 모두 새로운 내용을 새로운 HTML항목으로 바꿀 때 사용
- object.outerText
:: 해당 텍스트를 포함하고 있는 태그 요소까지 모두 새로운 텍스트로 변경되어 진다.