1. 함수
기본적으로 다음과 같은 4가지의 역할을 가지고 있다.
function 생성자는 잘쓰이지 않음
04-01.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-01</title>
</head>
<body>
<script type="text/javascript">
// 함수의 정의와 호출
// function 문에 의해 정의된 print 함수는 매개변수 message에 전달된 값을 출력합니다.
function print(message) {
document.writeln(message);
}
// function 문에 의해 정의된 println 함수는 매개변수 message에 전달된 값과
// 문자열 '<br/>'을 접합연산한 결과를 출력합니다.
function println(message) {
document.writeln(message + '<br/>');
}
// function 문에 의해 정의된 distance 함수는 x, y 프로퍼티를 가진 객체를 매개변수로 하여
// 내장객체 Math가 제공하는 sqrt함수를 호출해 두 점간의 거리를 반환합니다.
function distance(p1, p2) {
var dX = p2.x - p1.x;
var dY = p2.y - p1.y;
return Math.sqrt(dX * dX, dY * dY); // 내장객체 Math가 제공하는 sqrt함수를 호출합니다.
}
var pointA = { x : 25, y : 40 };
var pointB = { x : 50, y : 80 };
print('pointA와 pointB 사이의 거리: ');
println(distance(pointA, pointB));
// 함수리터럴에 의해 정의된 area 함수는 x, y 프로퍼티를 가진 객체를 매개변수로 하여
// 두 점을 이용해 구성된 사각형의 면적을 반환합니다.
var square = function(leftTop, rightButtom) {
var width = rightButtom.x - leftTop.x;
var height = rightButtom.y - leftTop.y;
return width * height;
};
print('pointA와 pointB로 구성한 사각형의 넓이: ');
println(square(pointA, pointB));
// Function 생성자에 의해 정의된 triangle 함수는 base와 height 매개변수에 전달된 값을 이용해
// 삼각형의 면적을 반환합니다.
var triangle = new Function('base', 'height', 'return (base * height) / 2;');
print('base와 height로 구성한 삼각형의 넓이: ');
println(triangle(30, 20));
</script>
</body>
</html>
출력화면
2. 변수의 전역스코프와 지역스코프
04-02.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-02</title>
</head>
<body>
<script type="text/javascript">
// 전역 스코프와 지역 스코프
// 전역 스코프를 가진 전역 변수
var x = 'global x';
var y = 'global y';
function func() {
// 지역 스코프를 가진 지역 변수는 반드시 var 키워드와 함께 선언되어야 합니다.
var x = 'local x';
// var 키워드 없을 경우 전역스코프에 접근해 동일 이름을 가진 전역변수를 사용하며,
// 만일 동일 이름의 전역 변수가 없을 경우 전역변수를 새로 등록합니다.
y = '???';
document.writeln('x: ' + x + '<br/>');
document.writeln('y: ' + y + '<br/>');
document.writeln('<br/>');
}
document.writeln('func() 호출 전<br/>');
document.writeln('x: ' + x + '<br/>');
document.writeln('y: ' + y + '<br/>');
document.writeln('<br/>');
document.writeln('func() 호출<br/>');
func();
document.writeln('func() 호출 후<br/>');
document.writeln('x: ' + x + '<br/>');
document.writeln('y: ' + y + '<br/>');
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
3. 함수의 매개변수와 스코프
04-03.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-03</title>
</head>
<body>
<script type="text/javascript">
// 함수의 매개변수와 스코프
// 값을 매개변수로 전달하는 경우 함수 내에서의 매개변수 조작은 원본 값에 아무런 영향을 미치지 않습니다.
function swapByValue (x, y) {
var temp = x;
x = y;
y = temp;
}
// 참조값을 매개변수로 전달하는 경우 매개변수가 원본 객체를 참조하므로
// 함수 내에서 매개변수를 통한 객체 조작은 원본 객체에 영향을 미칩니다.
function swapByReference (o) {
var temp = o.x;
o.x = o.y;
o.y = temp;
}
var a = 5;
var b = 8;
var obj = { x : 5, y : 8};
document.writeln('swap 함수 호출 전<br/>');
document.writeln('a: ' + a + ', b: ' + b + '<br/>');
document.writeln('obj.x: ' + obj.x + ', obj.y: ' + obj.y + '<br/>');
document.writeln('<br/>');
swapByValue(a, b);
swapByReference(obj);
document.writeln('swap 함수 호출 후<br/>');
document.writeln('a: ' + a + ', b: ' + b + '<br/>');
document.writeln('obj.x: ' + obj.x + ', obj.y: ' + obj.y + '<br/>');
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
4. 함수의 매개변수와 인자
04-04html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-04</title>
</head>
<body>
<script type="text/javascript">
// 함수의 생략 가능한 매개변수
function sum(array, start, end) {
// 매개변수 array에 전달된 값이 없을 경우 빈 배열을 할당합니다.
// if 문을 대신해 다음의 || 연산자를 이용한 조건문을 작성할 수도 있습니다.
// array = array || [];
if (!array)
array = [];
// 매개변수 start에 전달된 값이 없을 경우 0을 할당합니다.
if (!start) start = 0;
// 매개변수 end에 전달된 값이 없을 경우 배열의 원소의 갯수를 할당합니다.
if (!end) end = array.length;
// 매개변수 array에 전달된 값이 배열 객체일 경우에만 합계를 계산합니다.
if (array instanceof Array) {
// 매개변수 start와 end에 전달된 값이 숫자일 경우에만 합계를 계산합니다.
if ((typeof start) != 'number' || (typeof end) != 'number')
throw new Error('sum(): 두번째 매개변수와 세번째 매개변수의 전달 인자는 숫자여야 합니다.');
var result = 0;
for (var i = start; i < end; i++) {
// 배열 array의 원소가 숫자 타입일 경우에만 합계를 계산합니다.
if ((typeof array[i]) != 'number')
throw new Error('sum(): array[' + i + ']에 저장된 값 ' + array[i] + '는 숫자 타입이 아닙니다.');
result += array[i];
}
return result;
} else { // 매개변수 array에 전달된 값이 배열 객체가 아닐 경우 예외를 발생시킵니다.
throw new Error('sum(): 첫번째 매개변수의 전달 인자는 배열이어야 합니다.');
}
}
var arr1 = [1,2,3,4,5];
var obj = { name : '홍길동', phone : '010-1234-5678' };
var arr2 = [1,2,'3rd',4,5];
try {
document.writeln('sum(arr1, 0, arr1.length): ' + sum(arr1, 0, arr1.length) + '<br/>');
document.writeln('sum(arr1, 0, 4): ' + sum(arr1, 0, 4) + '<br/>');
document.writeln('sum(arr1, 0): ' + sum(arr1, 0) + '<br/>');
document.writeln('sum(arr1, 2): ' + sum(arr1, 2) + '<br/>');
document.writeln('sum(arr1): ' + sum(arr1) + '<br/>');
document.writeln('sum(): ' + sum() + '<br/>');
document.writeln('sum(obj): ' + sum(obj) + '<br/>');
} catch (e) {
document.writeln(e + '<br/>');
}
try {
document.writeln('sum(arr1, \'x\', 4): ' + sum(arr1, 'x', 4) + '<br/>');
} catch (e) {
document.writeln(e + '<br/>');
}
try {
document.writeln('sum(arr2): ' + sum(arr2) + '<br/>');
} catch (e) {
document.writeln(e + '<br/>');
}
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
5. 함수와 명시적인 이름을 가진 인자 전달
04-05.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-05</title>
</head>
<body>
<script type="text/javascript">
// 함수와 명시적인 이름을 가진 인자 전달
function power(arg) {
// 매개변수 arg로 전달된 객체에 base프로퍼티가 정의되어 있지 않을 때
// base프로퍼티를 추가하며 1로 설정합니다.
if (!arg.base) {
arg.base = 1;
}
// 매개변수 arg로 전달된 객체에 exponent프로퍼티가 정의되어 있지 않을 때
// exponent프로퍼티를 추가하며 0으로 설정합니다.
if (!arg.exponent) {
arg.exponent = 0;
}
// 내장객체 Math의 pow 함수를 호출해 결과를 반환합니다.
return Math.pow(arg.base, arg.exponent);
}
document.writeln('power({base:3, exponent:2})의 결과 값: ' + power({base:3, exponent:2}) + '<br/>');
document.writeln('power({base:3})의 결과 값: ' + power({base:3}) + '<br/>');
document.writeln('power({exponent:2})의 결과 값: ' + power({exponent:2}) + '<br/>');
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
6. 함수에 인자로 함수를 전달
04-06.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-06</title>
</head>
<body>
<script type="text/javascript">
// 사칙연산 관련 메소드를 가진 calculator객체를 정의합니다.
var calculator = {
add : function(x, y) {
return x + y;
},
subtract : function(x, y) {
return x - y;
},
multiply : function(x, y) {
return x * y;
},
divide : function(x, y) {
return x / y;
}
};
// 위에 정의된 calculator 객체의 메소드를 첫번째 매개변수의 전달 값으로,
// 나머지 두 개의 매개변수는 첫번째 매개변수로 전달된 calculator 객체의 메소드의
// 매개변수로 사용할 operate1 함수를 정의합니다.
function operate1(operator, operand1, operand2) {
return operator(operand1, operand2);
}
// 첫번째 매개변수로 calculator 객체의 프로퍼티명을 전달하고, 나머지 두 개의 매개변수는
// calculator 객체의 메소드의 매개변수로 사용할 operate2 함수를 정의합니다.
function operate2(operatorName, operand1, operand2) {
// 프로퍼티 타입이 함수일 경우 그 메소드를 실행합니다.
if ((typeof calculator[operatorName]) == 'function')
return calculator[operatorName](operand1, operand2);
else
throw new Error('operator2(): ' + operatorName + '은(는) 정의되어 있지 않은 연산자입니다.');
}
// ((3 - 8) + (2 * 5))
var result1 = operate1(calculator.add, operate1(calculator.subtract, 3, 8),
operate1(calculator.multiply, 2, 5));
document.writeln('result1: ' + result1 + '<br/>');
try {
var result2 = operate2('add', operate2('subtract', 3, 8), operate2('multiply', 2, 5));
document.writeln('result2: ' + result2 + '<br/>');
} catch (e) {
document.writeln(e + '<br/>');
}
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
7.함수에 함수 리터럴을 전달하는 익명함수
04-07.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-07</title>
</head>
<body>
<script type="text/javascript">
// 함수에 함수 리터럴을 전달하는 익명함수
var calculator = {
// operate 메소드의 첫번째 매개변수는 함수를 인자로 전달 받습니다.
operate : function(method, operand1, operand2) {
if (typeof method == 'function') {
if (typeof operand1 != 'number' || typeof operand2 != 'number')
throw new Error('operate(): 두번째, 세번째 매개변수는 반드시 숫자를 전달해야 합니다.');
return method(operand1, operand2);
} else
throw new Error('operate(): 첫번째 매개변수로 함수를 전달해야 합니다.');
}
};
try {
// calculator.operate 메소드의 첫번째 매개변수로 익명함수를 전달합니다.
var result1 = calculator.operate(function(x, y){ return x + y; }, 2, 3);
document.writeln('result1: ' + result1 + '<br/>');
// 두번째, 세번째 매개변수로 숫자가 아닌 값을 전달하면 예외를 발생시킵니다.
var result2 = calculator.operate(function(x, y){ return x + y; }, '2', 3);
document.writeln('result2: ' + result2 + '<br/>');
} catch (e) {
document.writeln(e + '<br/>');
}
document.writeln('<br/>');
// 익명함수를 정의하고 바로 호출해 결과를 얻을 수도 있습니다.
var result3 = (function(x, y){ return x + y;})(2, 3);
document.writeln('result3: ' + result3 + '<br/>');
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
8.중첩 함수
04-08.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-08</title>
</head>
<body>
<script type="text/javascript">
// 중첩함수
function circle(radius) {
var pi = 3.14;
// 중첩함수는 내부 변수에 접근가능합니다.
function area(r) {
return r * r * pi;
}
// 중첩함수는 내부에서만 호출 가능합니다.
return area(radius);
}
document.writeln('circle(5): ' + circle(5) + '<br/>');
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
9. 스코프 체인
04-09.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-09</title>
</head>
<body>
<script type="text/javascript">
// 스코프 체인
// 1. 전역 레벨의 파싱 결과 전역객체에 프로퍼티 x와 outer가 정의됩니다.
var x = '전역 객체에 등록되어 있는 x 프로퍼티 값';
function outer() {
var y = 'outer 함수의 호출 객체에 등록되어 있는 y 프로퍼티 값';
function inner() {
var z = 'inner 함수의 호출 객체에 등록되어 있는 z 프로퍼티 값';
document.writeln('x: ' + x + '<br/>');
document.writeln('y: ' + y + '<br/>');
document.writeln('z: ' + z + '<br/>');
}
// 3. 함수 레벨의 파싱 결과 inner 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화되고,
// 프로퍼티 z가 정의되고,
// outer 함수의 호출 객체와 inner 함수의 호출 객체 간에 스코프 체인이 연결되고,
// inner 함수의 코드를 실행합니다.
// 이 때 x는 전역객체에, y는 outer 함수의 호출객체에, z는 inner 함수의 호출객체에 접근해서
// 그 값을 취합니다.
inner();
}
// 2. 함수 레벨의 파싱 결과 outer 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화되고,
// 프로퍼티 y와 inner가 정의되고,
// 전역객체와 outer 함수의 호출 객체 간에 스코프 체인이 연결된 후,
// outer 함수의 코드를 실행합니다.
outer();
document.writeln('<br/>');
</script>
</body>
</html>
출력화면
10. 콜백 함수
04-10.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-10</title>
</head>
<body>
<script type="text/javascript">
// 콜백함수
function main() {
var array = [];
// 내장객체 Math의 random 함수는 0 ~ 1 사이의 값을 반환하고,
// 내장객체 Math의 ceil 함수는 인자 값 이상의 최소 정수를 반환합니다.
for (var i = 0; i < 10; i++) {
array[i] = Math.ceil(Math.random() * 45);
}
// work 함수를 호출하면서 첫번째 매개변수로 처리할 데이터 data를,
// 두번째, 세번째 매개변수로 콜백함수 even과 odd를 전달합니다.
work(array, even, odd);
}
// 콜백함수 even은 짝수가 발견될 때마다 호출될 함수로 당시의 배열 인덱스와 원소를 출력합니다.
function even(idx, num) {
document.writeln((idx + 1) + '번째 데이터는 짝수 ' + num + '입니다.<br/>');
}
// 콜백함수 odd는 홀수가 발견될 때마다 호출될 함수로 당시의 배열 인덱스와 원소를 출력합니다.
function odd(idx, num) {
document.writeln((idx + 1) + '번째 데이터는 홀수 ' + num + '입니다.<br/>');
}
// work 함수는 매개변수로 전달받은 배열 data에서
// 짝수가 발견될 때마다 매개변수로 전달받은 콜백함수 callback1를 호출하고,
// 홀수가 발견될 때마다 매개변수로 전달받은 콜백함수 callback2를 호출합니다.
function work(data, callback1, callback2) {
for (var i = 0; i < data.length; i++) {
if (data[i] % 2 == 0)
callback1(i, data[i]);
else
callback2(i, data[i]);
}
}
// main 함수를 실행합니다.
main();
</script>
</body>
</html>
출력화면
11. 비공개 속성/함수를 만들 수 있는 함수 클로저 (가장 중요!!)
04-11.html
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<title>04-11</title>
</head>
<body>
<script type="text/javascript">
// 클로저
// 1. 전역 레벨의 파싱 결과 전역객체에 프로퍼티 makeId와 id가 정의됩니다.
function makeId() {
var lastId = 0;
return function() { return ++lastId; };
}
// 2. 함수레벨의 파싱 결과 makeId() 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화 되고,
// 프로퍼티 lastId가 정의되고,
// 전역객체와 makeId() 함수의 호출객체 간에 스코프 체인이 연결된 후,
// makeId() 함수가 실행되고, id는 익명함수를 반환받습니다.
var id = makeId();
// 3. 함수 레벨의 파싱 결과 id 함수에 대한 호출 객체에 arguments 프로퍼티가 초기화되고,
// makeId 함수의 호출 객체와 id 함수의 호출 객체 간에 스코프 체인이 연결되고,
// id 함수의 코드를 실행합니다.
// 이 때 lastId는 makeId 함수의 호출객체에 접근해서
// 그 값을 취합니다.
document.writeln('id: ' + id() + '<br/>');
document.writeln('id: ' + id() + '<br/>');
document.writeln('id: ' + id() + '<br/>');
document.writeln('id: ' + id() + '<br/>');
document.writeln('id: ' + id() + '<br/>');
document.writeln('<br/>');
</script>
</body>
</html>
출력 화면
'프로그래밍 > 자바스크립트' 카테고리의 다른 글
Javascript - 웹브라우저 별 이벤트 처리 (0) | 2015.01.25 |
---|---|
Javascript - 객체 생성 과정 및 상속 (0) | 2015.01.25 |
Javascript - 로또 번호 생성기 만들기 (0) | 2015.01.23 |
Javascript - 객체 (0) | 2015.01.23 |
Javascript - 함수 유효범위와 클로저 (0) | 2015.01.22 |
Javascript - 연산자, 제어문, 예외처리 (0) | 2015.01.21 |
Javascript - 변수, 데이터 타입, 리터럴 (0) | 2015.01.21 |
자바스크립트 - EJS 형식에서 forEach문 의미 및 사용법 (0) | 2015.01.06 |