제어 구문은 프로그램의 처리 흐름을 제어하는 문장이다. 제어 구문을 배우면 알고리즘에 담긴 논리를 표현할 수 있고 본격적으로 프로그램을 만날 수 있다.
문장은 위에서부터 아래 방향으로 작성한 순서대로 실행된다 => 순차적 실행
순차적 실행 흐름을 변화시키는 문장을 제어 구문이라고 한다.
분류 | 제어 구문 | 설명 |
조건문 | if/else, switch, try/catch/finally | 조건에 따라 처리를 분기 |
반복문 | while, do/while, for, for/in, for/of | 조건을 만족하면 처리를 반복 실행 |
점프문 | break, continue, throw | 프로그램의 다른 위치로 이동 |
조건문
조건문은 조건식의 값에 따라 실행 흐름을 분기한다.
if / else
'만약 ~ 이라면 ... 그렇지 않으면 ...'
조건의 만족 여부에 따라 처리할 작업을 선택한다.
1. if ( 조건식 ) 문장
2. if ( 조건식 ) 문장 1 else { 문장2 }
- 조건식을 묶은 소괄호는 꼭 입력해야 한다.
- 문장을 여러 줄 작성하려면 블록 문장을 사용한다.
- if 문 안에 if 문을 작성할 수 있다. ( 중첩된 if 문 )
- else 절은 가장 가까운 if에 호응한다.
- 실행할 문장이 하나여도 문장을 중괄호로 묶는걸 권장한다.
// 윤년인지 확인하는 함수
function isLeapYear(year) {
if( (year % 400 == 0 ) || ( (year % 4 == 0 ) && (year % 100 != 0) ) ) {
return true;
}
return false;
}
isLeapYear(2020); // true
isLeapYear(2022); // false
- 윤년이란 ? https://docs.microsoft.com/ko-kr/office/troubleshoot/excel/determine-a-leap-year
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>고혈압 여부 확인하기</title>
<script>
window.onload = function() {
document.getElementById("button").onclick = function() {
// 수축기 혈압 (최고 혈압)을 구한다
var hp = parseFloat(document.getElementById("highpressure").value);
// 이완기 혈압 (최저 혈압)을 구한다
var lp = parseFloat(document.getElementById("lowpressure").value);
// 판정 결과를 내보낼 HTML 요소
var judgement = document.getElementById("judgement");
// 고혈압 여부를 판정하여 HTML 요소에 출력한다
if( hp<120 && lp<80 ) {
judgement.innerHTML = "당신의 혈압은 정상입니다";
} else if( hp<139 && lp<89 ) {
judgement.innerHTML = "당신의 혈압은 다소 높습니다";
} else {
judgement.innerHTML = "당신은 고혈압입니다";
}
};
};
</script>
</head>
<body>
<p>수축기 혈압 (최고 혈압) : <input type="number" id="highpressure"></p>
<p>이완기 혈압 (최저 혈압) : <input type="number" id="lowpressure"></p>
<p id="judgement">이곳에 판정 결과가 표시됩니다 </p>
<input type="button" id="button" value="확인하기">
</body>
</html>
- https://jsfiddle.net/Kimara/6h4dg9xt/
switch
- 분기점 여러 개를 더욱 간결하게 표현할 수 있다.
switch(표현식) {
case 표현식 1 : 실행문 1 (문장 여러개)
case 표현식 2 : 실행문 2 (문장 여러개)
...
case 표현식 n : 실행문 n (문장 여러개)
default : 실행문 n + 1 (문장 여러개)
}
- case 바로 뒤에 작성하는 표현식의 값을 case 라벨의 값이라고 한다.
- 옵션으로 default 라벨 한 개를 추가로 작성할 수 있다.
- switch 문이 실행되면 먼저 괄호 안에 들어있는 표현식을 평가하고 평가한 값과 일치하는 case 라벨의 값을 위에서부터 아래 방향으로 찾는다.
- 라벨 값과 일치하는 case 라벨을 발견하면 그 case 라벨에 속한 블록 문장을 차례대로 실행한다.
- 일치하는 값을 찾지 못하면 default 를 실행한다.
- 값이 일치하는 case 라벨과 default 라벨을 발견하지 못하면 아무것도 하지 않는다.
- 자바스크립트에서는 표현식을 그대로 쓸 수 있다(C나 Java에서는 case 뒤에 반드시 상수 값을 써야한다.)
function binaryOperation(a, b, operator) {
switch(operator) {
case "+": return a + b;
case "-": return a - b;
case "*": return a * b;
case "/": return a / b;
case "%": return a % b;
case "^": return Math.pow(a, b); // 지정된 숫자의 지정된 거듭제곱을 반환
default: return NaN;
}
}
console.log(binaryOperation(2,3,"+")); // 5
console.log(binaryOperation(2,3,"-")); // -1
console.log(binaryOperation(2,3,"*")); // 6
console.log(binaryOperation(2,3,"^")); // 8
console.log(binaryOperation(2,3,"A")); // NaN
- break 문이 실행되면 블록 문장에서 빠져나와 다음 작업을 시작한다.
- switch 문의 case 라벨은 분기의 시작을 명시할 뿐 분기의 끝을 명시하지는 않는다.
- break 문을 하나도 사용하지 않으면 case 라벨로 분기한 다음에 그 라벨 뒤에 등장하는 전체 문장을 실행한다.
- 함수 끝에 switch 문을 사용하면 break 문 대신 return 문을 사용해도 똑같은 다중 분기를 표현할 수 있다.
- break나 return 문을 사용하지 않으면 switch 블록의 끝을 만날때까지 발견한 모든 문장을 실행 => 풀 스루(fall through) 이는 지양한다.
- default 라벨은 switch 블록 어느 위치에 있어도 문법 오류가 발생하지 않는다. 다만 프로그램 이해도를 위해 마지막에 쓰는걸 지향한다.
반복문
반복문은 일정한 처리를 한 다음 원래 위치로 돌아가 똑같은 처리를 반복하는 처리를 표현한다.
while
- 조건만 맞아떨어지면 일정한 처리를 계속 반복해서 실행한다.
while (조건식) {
문장(표현식의 결과가 참인 동안 반복적으로 실행하고자 하는 실행문)
}
* while 문 안에서 break를 실행하면 while 문에서 빠져나온다.
* while 문 안에서 continue를 실행하면 while 문의 시작 부분으로 되돌아간다.
- 조건식을 평가
- 결과가 false면 while 문을 빠져 나와 다음 처리로 이동한다.
- 결과가 true면 문장을 실행하고 다시 한번 while 문의 시작 부분으로 돌아가서 조건식을 평가한다.
// 정수 n의 팩토리얼을 구하는 함수
function fact(n) {
var k = 1, i = 1;
while( i < n ) {
console.log("i = " + i + ", k = " + k );
k *= (++i);
}
console.log("i = " + i + ", k = " + k );
return k;
}
fact(5); // 120
/*
i = 1, k = 1
i = 2, k = 2
i = 3, k = 6
i = 4, k = 24
i = 5, k = 120
120
*/
- console.log를 사용해서 반복문 안의 변수 값을 추적하는 방법은 프로그램의 동작을 확인하고 디버깅을 할 때 활용할 수 있는 간단하고 효과적인 방법이다.
// 순차 검색
function linearSearch(x, a) {
var i=0;
var n = a.length;
while( i < n && x > a[i] ) i++;
if( x == a[i] ) return i;
return null;
}
let a = [2,4,7,12,15,21,34,35,46,57,70,82,86,92,99];
console.log(linearSearch(35,a)); // 7
- 배열 a에서 x값과 같은 요소를 찾아내는 알고리즘이다.
- 순차 검색은 단순히 왼쪽 요소부터 차례대로 x 값과 비교해서 같은 값을 가진 요소를 찾아낸다.
- 배열 a에서 x와 같은 요소를 발견하면 그 요소를 반환하고 발견하지 못하면 null을 반환한다.
// 이진 검색
function binarySearch(x,a) {
var n = a.length;
var left = 0, right = n-1;
while( left < right ) {
var middle = Math.floor((left+right)/2);
if( x<=a[middle] ) {
right = middle;
} else {
left = middle+1;
}
}
if( x == a[right] ) return right;
return null;
}
let a = [2,4,7,12,15,21,34,35,46,57,70,82,86,92,99];
console.log(binarySearch(35,a)); // 7
- 배열 중간 요소인 a[middle]과 x를 비교한다.
- x <= a[middle]이면 x와 같은 요소는 왼쪽 절반 안에 있다. 따라서 왼쪽 부분을 다음 검색 대상으로 삼는다.
- 이렇게 검색 범위를 좁혀 나가면 한 번에 검색해야 하는 범위가 절반씩 줄어든다.
- 범위가 0이 될 때까지 반복한다.
- 배열 a에서 x와 같은 요소를 발견하면 그 요소를 반환하고 발견하지 못하면 null을 반환한다.
do / while
- do / while 문은 반복해서 실행할지를 마지막 부분에서 판단한다.
do {
문장(표현식의 결과가 참인 동안 반복적으로 실행하고자 하는 실행문)
} while (조건식);
- do/while 문 끝에는 반드시 세미콜론이 붙는다.
- 먼저 문장을 실행하고 뒤에 조건식을 평가한다.
- 조건식을 평가한 결과가
- false 면 do/while 문을 빠져 나와 다음 처리로 이동한다.
- true면 반복문의 시작 부분으로 되돌아간다.
- do/while 문 안에 있는 문장은 반드시 한 번 이상 실행된다.
- break와 continue 문을 사용할 수 있다.
// 정수 n의 팩토리얼을 구하는 함수
function fact(n) {
var k = 1, i = n;
do {
k *= i--;
} while( i>0 );
return k;
}
fact(5); // 120
- while 문에서는 k에 곱하는 i 값을 1부터 1씩 증가시켰지만,
- do / while 문에서는 i를 n부터 1씩 감소한다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>뉴턴-랩슨 법으로 제곱근 구하기</title>
</head>
<body>
<script>
var EPSILON= 1.0e-10;
var d,xnew,xold;
var a = parseFloat(prompt("정수를 입력하십시오"));
xold = ( a>1 )? a : 1.0;
do {
xnew = xold - ( xold*xold - a )/(2.0*xold);
d = (xold - xnew)/xold;
xold = xnew;
} while( d > EPSILON );
document.write("sqrt(" + a + ") = " + xnew);
</script>
</body>
</html>
- .............????????????????????????????????????????????
하하..
while 문과 do / while 문의 차이점은 조건을 먼저 검사하느냐 나중에 검사하느냐일 뿐 동작 방식은 동일하다.
* while 문은 반복문 처음부터 조건을 따져 반복문을 실행
* do / while 문은 반복을 한번 실행 후 조건식을 따진다.
for
반복문의 세가지 공통점
- 반복 조건의 초기화 작업
- 반복문의 조건식
- 반복 작업이 하나 끝났을 때 반복 조건을 갱신하는 작업
for (초기화 식; 조건식; 반복식) {
문장(표현식의 결과가 참인 동안 반복적으로 실행하고자 하는 실행문)
}
- 반복문을 시작하기 전에 초기화식을 단 한 번 실행한다.
- 그 후에 반복 작업을 시작하는데 이때 조건식을 먼저 평가한다.
- 조건식을 평가한 결과가
- false면 for 문을 빠져 나와 다음 처리로 이동한다.
- true면 문장을 실행한 후에 반복식을 실행한다. 그리고 다시 한번 for문의 시작 부분으로 돌아가서 조건식을 평가한다.
- break와 continue 문을 사용할 수 있다.
- 초기화 식을 입력하는 부분에 쉼표 연산자를 사용하면 표현식을 여러 개 작성할 수 있다.
- 초기화 식, 조건식, 반복식은 모두 생략할 수 있다. 단, 소괄호 안에 있는 세미콜론은 생략할 수 없다.
- 조건식을 생략하면 끝없이 반복한다는 뜻이다.
// 배열 요소의 합계 구하기
function sumArray(a) {
var sum = 0;
for(var i=0; i < a.length; i++) {
sum += a[i];
}
return sum;
}
var a = [3,5,1,2,6,7];
console.log(sumArray(a)); // 24
- 배열 번호로 반복문을 만들 때는 i <= a.length -1 대신 i < a.length 라고 쓰는 것이 관례이다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>에라토스테네스의 체로 쌍둥이 소수 구하기</title>
</head>
<body>
<script>
var n = parseInt(prompt("n?"));
// 에라토스테네스의 체로 소수를 구한다
var p = []; // 아래의 i가 소수이면 p[i] = true, 합성수이면 p[i] = false 로 처리한다
for (var i = 2; i <= n; i ++) p[i] = true; // 먼저, 2 ~ n 사이의 모든 정수를 소수로 간주한다
var max = Math.floor(Math.sqrt(n)); // 소수 x는 √n까지 구하면 충분하다
var x = 2;
while(x<=max) {
for (var i = 2 * x; i <= n; i += x) p[i] = false; // x의 배수는 합성수
while (!p[++x]); // 다음 소수를 찾는다
}
// 쌍둥이 소수 출력
for(var i=2; i<=n-2; i++) {
if(p[i] && p[i+2]) {
document.write(i+","+(i+2)+"<br>");
}
}
</script>
</body>
</html>
- ..............????????????????????????????????????????????
- https://themarketer.tistory.com/73 함 봐보면 재밌다...
하하..2
중첩 반복문
- for 문 안에 for 문을 작성하면 중첩 반복문을 만들 수 있다.
// 피타고라스의 수 구하기
var n = 20;
for(var a = 1; a <= n; a++) {
for(var b = 1; b <= n; b++) {
for(var c = 1; c <= n; c++) {
if( a*a + b*b == c*c ) {
console.log(a + "^2 + " + b + "^2 = " + c + "^2");
}
}
}
}
/*
3^2 + 4^2 = 5^2
4^2 + 3^2 = 5^2
5^2 + 12^2 = 13^2
6^2 + 8^2 = 10^2
8^2 + 6^2 = 10^2
8^2 + 15^2 = 17^2
9^2 + 12^2 = 15^2
12^2 + 5^2 = 13^2
12^2 + 9^2 = 15^2
12^2 + 16^2 = 20^2
15^2 + 8^2 = 17^2
16^2 + 12^2 = 20^2
*/
- 피타고라스의 수는 a²+b²=c² 을 만족하는 자연수 a,b,c의 쌍을 말한다.
- a,b,c 값을 1에서 20까지 증가시킨다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>원의 N분점을 연결하는 직선 그리기</title>
<script>
function diamond(c,n,x,y,r,color) {
var p = generatePoints(n,x,y,r);
c.strokeStyle = color;
c.beginPath();
for(var i = 0; i < n; i++) {
for(var j = i + 1; j < n; j++) {
c.moveTo(p[i].x, p[i].y);
c.lineTo(p[j].x, p[j].y);
}
}
c.stroke();
}
function generatePoints(n,x,y,r) {
var points = [];
for(var i = 0; i < n; i++) {
var t = i * 2 * Math.PI / n;
points[i] = {
x: x + r * Math.cos(t),
y: y + r * Math.sin(t)
};
}
return points;
}
window.onload = function() {
var canvas = document.getElementById("mycanvas");
var ctx = canvas.getContext("2d");
diamond(ctx, 6,170,170,150,'darkblue');
diamond(ctx,12,490,170,150,'darkblue');
diamond(ctx,18,810,170,150,'darkblue');
};
</script>
</head>
<body>
<canvas id="mycanvas" width="1000" height="400"></canvas>
</body>
- .............????????????????????????????????????????????
- https://jsfiddle.net/Kimara/6h4dg9xt/4/
하하..3
for / in
- for / in 문은 객체 안의 프로퍼티를 순회하는 반복문이다.
for (변수 in 객체 표현식) {
문장(객체의 모든 열거할 수 있는 프로퍼티의 개수만큼 반복적으로 실행하고자 하는 실행문)
}
- for / in 문이 실행되면 먼저 객체 표현식을 평가한다.
- 객체 표현식이
- null 또는 undefined로 평가되면 for / in 문을 빠져나와 다음 작업으로 이동한다.
- 객체로 평가되면 객체의 프로퍼티 이름이 차례대로 변수에 할당되고 각각의 프로퍼티에 대해서 문장이 한 번씩 실행된다.
var obj = { a: 1, b: 2, c: 3 };
for(var p in obj) {
console.log(`p = ${p}`);
}
/*
p = a
p = b
p = c
*/
- 각 프로퍼티 이름을 "a", "b", "c" 라는 문자열로 바꾸어 변수 p에 대입하는 문장이 실행된다.
var obj = { a: 1, b: 2, c: 3 };
for(var p in obj) {
console.log(`obj.${p} = ${obj[p]}`);
}
/*
obj.a = 1
obj.b = 2
obj.c = 3
*/
- 프로퍼티 이름만 꺼내 변수에 할당한다. 따라서 반복문 안에서 프로퍼티 값을 가져오려면 괄호 연산자를 사용해야 한다.
- break 문과 continue 문을 사용할 수 있다.
점프문
점프문은 프로그램의 다른 위치로 이동하는 제어 구문이다.
자바스크립트에서 사용할 수 있는 점프문에는 break, continue, return, throw 가 있다.
라벨문
- 자바스크립트에서는 모든 문장에 라벨을 붙일 수 있으며 사용법은 다음과 같다.
라벨 이름 : 문장
- 라벨 이름에는 모든 식별자를 사용할 수 있다.
- 자바스크립트에서 라벨로 점프할 수 있는 문장은 break 문과 continue 문뿐이다.
- break 문은 switch 문과 반복문 안에서만 사용할 수 있고 continue 문은 반복문 안에서만 사용할 수 있다.
- 따라서 실제로 라벨을 붙여서 사용할 수 있는 문장은 switch 문과 반복문 뿐이다.
break 문
break;
- break 문은 swich 문과 반복문 안에서만 사용할 수 있다.
- 점프할 라벨을 지정할 수 있는데 사용법은 다음과 같다.
break 라벨 이름;
- 라벨을 지정한 break 문을 실행하면 라벨이 붙은 문장 끝으로 점프한다.
- 이때 라벨이 없으면 문법 오류가 발생한다.
- break 문과 라벨 이름 사이에는 줄 바꿈 문자를 넣지 않도록 주의해야 한다.
- 라벨을 지정한 break 문은 주로 중첩된 반복문의 안쪽 반복문 안에서 전체 반복문을 빠져나올 때 사용한다.
var a = [2,4,6,8,10], b = [1,3,5,7,9,11];
loop: for(var i = 0; i < a.length; i++) {
for(var j = 0; j < b.length; j++) {
if(a[i] == b[j]) break loop;
}
}
console.log(`a[${i}] = b[${j}]`); // a[5] = b[6]
- 배열 a와 배열 b에서 같은 값을 가진 요소를 발견하면 전체 반복문에서 빠져나온다.
continue 문
continue;
- 점프할 라벨을 지정할 수 있다.
continue 라벨 이름;
- 라벨 지정 여부와 관계없이 반복문 안에서만 사용할 수 있다.
* continue 문장이 반복을 새로 시작할 때의 동작
while 문 | 반복문의 처음으로 되돌아가서 조건식을 다시 평가한다. 그 결과가 true면 반복문을 처음부터 실행한다. | |||
do/while 문 | 중간을 건너띄고 반복문의 마지막 조건을 평가한다. 그 결과가 true면 반복문을 처음부터 실행한다. | |||
for 문 | 반복식을 실행한 후에 조건식을 평가한다. 그 결과가 true면 반복문을 이어서 실행한다. | |||
for/in 문 | 반복문의 처음으로 되돌아간다. 지정한 변수에 할당되어 있는 프로퍼티의 다음 프로퍼티를 대상으로 작업을 시작한다. |
var a = [2,5,-1,7,-3,6,9];
for(var i = 0, sum = 0; i < a.length; i++) {
if(a[i] < 0) continue;
sum += a[i];
}
console.log(sum); // 29
- 배열 a 안에서 값이 0 이상인 요소의 값을 모두 더한다.
var a = [[2,4,6,8], [1,5,12,3], [7,6,8,5], [5,15,3,4], [3,2,9,4]];
var max = Number.NEGATIVE_INFINITY; //음의 무한대를 나타냄
mainloop: for(var i = 0; i < a.length; i++) {
var average = 0;
for(var j = 0; j < a[i].length; j++){
if(a[i][j] > 10) continue mainloop;
average += a[i][j];
}
average /= a[i].length;
console.log(`i = ${i} : 평균값 = ${average}`);
if(max < average) max = average;
}
console.log(`최대 평균값 = ${max}`)
/*
i = 0 : 평균값 = 5
i = 2 : 평균값 = 6.5
i = 4 : 평균값 = 4.5
최대 평균값 = 6.5
*/
'Web > javascript' 카테고리의 다른 글
[자바스크립트] axios (0) | 2022.12.30 |
---|---|
[자바스크립트/HTML] Img onerror (0) | 2022.12.13 |
[자바스크립트] scrollY vs pageYOffset 무엇을 써야하나? (0) | 2021.03.19 |
[자바스크립트] 원시타입 참조타입 (0) | 2021.03.10 |
[자바스크립트] script의 async와 defer 속성 (0) | 2020.07.21 |