1인 스터디 2일차, 코뿔소 책 정리하기 2탄

egg-mari·2022년 7월 27일
0
post-thumbnail
post-custom-banner

1인 스터디 2일차

📕 오늘의 책 '러닝 자바스크립트'
✨ one-day, one-chapter
📑 CHAPTER.4

CHAPTER.4 제어문

반복 작업을 효율적으로 자동화하고 변화하는 조건에 대응 하기 위한 챕터

제어문 기초


while 루프

while 조건 을 만족하는 동안 코드를 계속 반복한다

	let funds = 50 
    while(funds > 1 && funds < 100){
 		// 100을 보다 낮고, 1보다 높으면 반복 실행
    	// 네버엔딩 무한 반복중..
    }

블록문 ({})

블록 문block statement 제어문은 아니지만 제어문과 함께 사용한다. (복합문 compound statement 라고도 한다)
블록 문은 문 statement 여러 개를 중괄호로 묶은 것이며 자바스크립는 이들을 하나의 단위로 취급한다. 제어문 없이 블록 문만 써도 되지만 별 의미는 없다.
블록 문이 유용해지는 것은 제어문과 함꼐 쓸 때 이다. 예를 들어서 위의 while문에서 실행하는 루프는 블록문 전체를 실행한 후 조건을 다시 테스트한다.

	let funds = 50 
    while(funds > 1 && funds < 100){
 		funds = funds + 2 
      	funds = funds - 1
      	// 100번 실행하고 끝남
    }

제어문제은 블록을 쓰는 것이 일반적이지만 생략도 가능하다.

	let funds = 50 
    while(funds > 1 && funds < 100) funds = funds + 2;

공백

대부분의 경우 자바스크립는 줄바꿈 문자를 포함해, 추가 공백을 신경 쓰지 않는다.
스페이스 하나는 스페이스 10개나 마찬가지고, 스페이스 10개나 빈 줄 10개나 마찬가지이다.
그렇다고 공백을 아무렇게나 쓰라는 말은 아니다.
아래의 예시 처럼 사용하게 되면 두 문 사이에 어떤 연관이 있다는 느낌을 주지 않고, 오해의 소지가 다분하기 때문에 피해야 한다.

	let funds = 50 
    while(funds > 1 && funds < 100)
      
      funds = funds + 2

조금 더 옳거나 흔히 쓰는 방식

	let funds = 50 
    while(funds > 1 && funds < 100) funds = funds + 2;

	while(funds > 1 && funds < 100) {funds = funds + 2;}

자바스크립트 자체가 오해할만한 코드

	let funds = 50 
    while(funds > 1 && funds < 100)
      funds = funds + 2; // 여기서 while까지의 바디(실행문)으로 인식
	  funds = funds - 1; // while이 다 끝나고 밖에서 실행

이렇게는 쓰지 말자!! 블록문과 블록이 없는 문을 섞어 쓰지 말자!

	let funds = 50 
    if(funds > 1) { 
    	//실행문
    } else // 실행문2
      
    if(funds > 1) 
      // 실행문
    else { // 실행문2 }
      
    //와 예시만 봐도 아찔하다 코드보다가 멘붕 올 듯..

do...while 루프

시작하면서 조건을 검사하지 않고 일단 실행하고, 마지막에 검사한다.
do...while 루프는 루프 바디를 최소 1번은 실행하려 할 때 사용한다.
while 루프의 조건이 거짓 같은 값으로 시작하면 루프 바디는 한번도 실행되지 않는다.

	let remaining = 3;
	do{
    	// 실행문
    }while (remainig > 0) 

for 루프

while, do while문을 for문으로 다 바꿔 쓸 수 있을 정도로 유연하지만,
for문에 가장 어울리는 작업은 따로 있다.
어떤 일을 정해진 숫자만큼 반복 할 때, 특히 그 일을 지금 몇 번째 하는 지 알아야할 때 사용한다.

	const hand = [];
	for(let roll=0; roll<3; roll++){
    	hand.push(roll*1)
    }

  // let roll = 0 (초기화) - 인덱스값의 초기값을 설정(roll은 변수이기때문에 무엇으로 설정하든 상관없다)
  // roll<3 (조건) - 얼만큼 반복문을 돌릴 지 정한다 이경우 0, 1, 2 까지 총 3번 돌겠군요.
  // roll++ (표현식)

if 문

if...else문과 if문의 차이, if...else문에서는 모든 분기가 행동으로 연결되어있지만 if 문에서는 분기 중 하나만 행동으로 연결됩니다.

책에서 만든 게임로직 합치기(모든 반복문 사용)

	// m 이상 n 이하의 무작위 정수를 반환
	function rand(m,n){
    	return m + Math.floor((n - m + 1)*Math.random());
    }
	
	function randFace(){
    	return ["crown", "achor","heart", "spade", "club", "diamond"][rand(0,5)]
    }

	let funds = 50; // 시작조건
	let round = 0;

	while(funds > 1 && funds < 100){
    	round++;
      	let bets = {crown : 0, anchor : 0, heart : 0, spade : 0, club : 0, diamond: 0};
      	let totalBet = rand(1,funds);
      	if(totalBet===7){
        	totaBet = funds;
          	bets.heart = totalBet
        }else {
        	let remaining = totalBet;
          	do{
            	let bet = rand(1, remaining);
              	let face = randFace();
              	bets[face] = bets[face] + bet;
              	remaining = remaining - bet;
            } while (remaining > 0) 
        }
        funds = funds -  totalBet;
        
        const hand = [];
        for(let roll=0; roll<3; roll++){
        	hand.push(randFace());
        }
          
        let winnings = 0;
        for (let die = 0; die < hand.length; die++){
        	let face = hand[die];
          	if(bets[face]> 0) winnings =  winnings + bets[face];
        }
        funds = funds + winnings;
        console.log(`\twiinings : ${winnings}`);
    }

자바스크립트의 제어문


제어문의 예외

제어문의 일반적인 실행 방식을 바꾸는 네가지 문
1. break - 루프 중간에 빠져나가기
2. continue - 루프에서 다음 단계로 바로 건너뛰기
3. return - 제어문을 무시하고 현재 함수를 즉지 빠져나가기
4. throw - 예외 핸들러에서 반드시 처리해야 할 예외를 일으킴. 현재 제어문 바깥에 있어도 무방

switch문

if...else보다 다양한 조건으로 가능. 조건을 값으로 평가할 수 있는 표현식 이다.
return은 즉시 함수를 빠져나가므로 break문 대신 사용 할 수 있다.
(react에서 reducer 작업할 떄 보면 break보다 return을 주로 쓴다. 약간 이런거 참고하면 좋을 듯?)

	switch(expression){
      case value1 : 
      	// expression을 평가한 결과가 value1 일 때 실헹  
        // ex :  expression의 "type1"(value1) 일 경우 "type1" 로 case를 지정 하면 true일 때 실행됨
	  break; //break가 없을 경우 계속 실행된다
      case value2:
      case value3:
        // 값 설정도 가능, 이 경우 2,3,4 모두 실행 됨.
      case value4:
        // value 2~4 모두 해당 바디 실행
      break
	  default : 
        // expression의 평가값이 아에 없을 경우 디폴트 값 실행
      break // 또는 retrun
    }

for...in 루프

객체의 프로퍼티 에 루프를 실행하도록 설계된 루프이다.
객체는 순서가 정해져있는 타입이 아니기때문에(array나 json와 같은 순서가 있는 것과는 다름) 브라우저를 실행할때마다 순서가 바뀔수도 있다. 중요한 건, for-in문을 순서대로 사용하고 싶다면 원하는 값을 얻을 수 없기 때문에 약간의 가공이 필요하다.
추가적으로 객체(object) 내장 메서드를 조금 공부해두자.

	const player = {name : 'Thomas', rank:'Midshipman', age: 25};
	for(let prop in player){
    	if(!player.hasOwnProperty(prop)) continue;
      	console.log(prop + ': ' + player[prop]);
    }

for...of 루프

ES6에 새로 생긴 반복문, 컬렉션의 요소에 루프를 실행하는 문법인데,
배열은 물론 이터러블(iterable)객체에 모두 사용할 수 있는 범용적인 루프이다.
배열에도 사용이 가능하지만 각 요소의 인덱스를 알아야 한다면 for을 사용하자.

	const hand = [randFace(), randFace(), randFace()];
	for(let i=0; i<hand.length; i++)
      console.log(`Roll ${i+1} : ${hand[i]}`);

유용한 제어문 패턴


continue 문을 사용하여 조건 중첩 줄이기

특정 조건이 맞을 때만 루프 바디를 실행해야 할 경우(제어문 중첩) countinue를 사용하여 간결하게 구조를 바꿀 수 있다.

	while(funds > 1 && funds < 100) {
    	let totalBet = rand(1, funds);
        if(totalBet === 13){
        	console.log("Unlucky! Skip this round....");
            continue;
        }
      	// body
    }

break, return 불필요한 연산 줄이기

break, return 모두 원하는 조건에 만족하면 더이상 루프문을 쓰지 않고 바로 루프 or 함수 빠져나온다. 불필요한 루프를 돌아서 성능을 저하시키는 것을 방지 할 수 있다.
루프가 함수 안에 있다면 return 사용 가능(switch 포함)

	let firstPrime = null;
	for(let n of bigArratOfNumbers){
    	if(isPrime(n)){
        	firstPrime = 0;
          	break;
        }
    }

마무리

continue 일하면서 별로 써본 적이 없다.
근데 일하면서 배열이나 객체를 이용하여 루프문을 돌리는 경우가 굉장히 많기 때문에,
해당 부분은 다시 머리속에서 상기시키기 좋은 예시들이 많았던 것 같다.
책에서는 간단하게 카드 게임을 이용하여 예시를 만들어서 했는데, 좋은 예시였던 것 같다.

profile
당신이 좋아하는 계란 마리
post-custom-banner

0개의 댓글