ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JavaScript 100제 1부 오답노트 (1~20)
    Language/JavaScript 2022. 9. 30. 20:23

    JEJU CODING BASE CAMP - CODE FESTIVAL

    JavaScript 100제 1부

     

    8. 객체의 키 이름 중복

    자바스크립트 객체를 다음과 같이 만들었다. 출력값을 입력하시오. (출력값은 공백을 넣지 않습니다. )

    var d = {
        'height':180,
        'weight':78,
        'weight':84,
        'temperature':36,
        'eyesight':1
    };
    
    console.log(d['weight']);

    -> 객체의 키 값이 중복되었을 경우, 마지막 키의 값을 가져온다. 따라서 출력값은 84이다.

     

    9. concat을 활용한 출력 방법

    다음 소스 코드를 완성하여 날짜와 시간을 출력하시오.

    var year = '2019';
    var month = '04';
    var day = '26';
    var hour = '11';
    var minute = '34';
    var second = '27';
    
    var result = //빈칸을 채워주세요
    
    console.log(result);
    
    /* 출력
    2019/04/26 11:34:27 */

    -> string.concat() 메소드는 string의 뒤에 붙일 요소를 괄호 안에 넣는다.

    따라서 var result = year.concat('/', month, '/', day, ' ', hour, ':', minute, ':', second); 가 답이다.

     

    10. 별 찍기

    크리스마스 날, 은비는 친구들과 함께 파티를 하기로 했습니다. 그런데, 크리스마스 트리를 사는 것을 깜빡하고 말았습니다. 온 가게를 돌아다녀 봤지만 크리스마스 트리는 모두 품절이었습니다. 하는 수 없이 은비는 프로그래밍으로 트리를 만들기로 합니다.

    은비를 위해 프로그램을 작성해 주세요.

    입력
    5
    
    출력
        *
       ***
      *****
     *******
    *********
    const n = prompt('숫자를 입력하세요.');
    let tree = '';
    
    for(let i=1; i<=n; i++){
      let star = '';
      for(let j=1; j<=n-i; j++){
        star += ' ';
      }
      for(let k=1; k<=2*i-1; k++){
        star += '*';
      }
      tree += star + '\n'; // '\n'은 줄바꿈
    }
    
    console.log(tree);

    -> 본 문제는 입력 값과 출력 값이 제시되어 있다. 즉 입력값에 따라 다른 출력 값을 얻도록 문제를 풀이해야 한다.

    // 내 첫 답안
    
    // 1. 스페이스바를 띄운다 4->3->2->1->0
    // 2. 별을 찍는다 1->3->5->7->9
    // 3. 다음 줄로 넘어간다
    
    let tree;
    
    for (let i = 0; i < 5; i++) {
    	tree = ' '.repeat(4 - i) + '*'.repeat(2*i + 1);
    	console.log(tree);
    }

    -> 줄 바꾸는 법을 몰라서 콘솔을 한줄씩 찍어내는 코드를 적었다.

     

    //수정한 내 답안
    let tree='';
    
    for (let i = 0; i < 5; i++) {
    	tree += ' '.repeat(4 - i)
    	tree += '*'.repeat(2*i + 1) + '\n';
    }
    console.log(tree);
    
    //출제자의 답안
    let tree = ''; // let tree;로 하면 tree가 undefined라서 콘솔 찍을때 undefined 값도 트리에 포함됨
    for (let i = 1; i<=5; i++) {
    	let star = ''; // let star;로 해도 마찬가지로 star가 undefined라서 콘솔찍을 때 star에 undefined 값이 포함됨
    	for (let j = 1; j<=5-j; j++) {
    		star += ' '
    	}
    	for (let k = 1; k<=2*i-1; k++) {
    		star += '*'
    	}
    	tree += star + '\n'
    }
    
    console.log(tree);
    
    //다른 사람의 또다른 답안
    //출처 : https://hianna.tistory.com/368
    for(let i = 0; i < 5; i++)  {
      for(let j=4; j > i; j--)  {
        // space
        document.write('&nbsp');
      }
      for(let j=0; j <= i; j++)  {
        document.write('*');
      }
      for(let j=1; j <= i; j++)  {
        document.write('*');
      }
      document.write('<br>');
    }
    
    //이사람의 답안을 개선한 답안
    for(let i = 0; i < 5; i++)  {
      for(let j=4; j > i; j--)  {
        // space
        document.write('&nbsp');
      }
      for(let j=0; j < 2*i+1; j++)  {
        document.write('*');
      }
      document.write('<br>');

     

    12. 게임 캐릭터 클래스 만들기

    다음 소스코드에서 클래스를 작성하여 게임 캐릭터의 능력치와 '파이어볼'이 출력되게 만드시오. 주어진 소스 코드를 수정해선 안됩니다.

    데이터
    <여기에 class를 작성하세요.>
    
    const x = new Wizard(545, 210, 10);
    console.log(x.health, x.mana, x.armor);
    x.attack();
    
    
    출력
    545 210 10
    파이어볼

    -> 클래스 문법을 알지 못해서 문법을 참고하여 풀었다.

    class Wizard {
      constructor (health, mana, armor) {
        this.health = health;
        this.mana = mana;
        this.armor = armor;
      }
      attack () {
        console.log('파이어볼')
      }
    }
    /* 위와 같다
    class Wizard {
      constructor (a, b, c) {
        this.health = a;
        this.mana = b;
        this.armor = c;
      }
      attack () {
        console.log('파이어볼')
      }
    }
    */
    
    
    const x = new Wizard(545, 210, 10); // new Wizard(a, b, c)
    console.log(x.health, x.mana, x.armor); // 545, 210, 10
    x.attack(); // '파이어볼'
    console.log(x); // { armor: 10, health: 545, mana: 210 }

    클래스는 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀로, 객체의 기본 상태를 설정해주는 생성자 메서드와 커스터마이징한 메서드(함수)로 구성된다.

     

    클래스는 함수처럼 클래스 표현식, 클래스 선언문 형식으로 선언할 수 있다.

    쉽게 생각하면 class 키워드는 객체를 만들어주는 함수라고 생각하면 쉽다.

     

    하지만, 함수와 다른 점은 함수는 매개변수를 괄호안에 넣으면 함수 몸체에 자동으로 변수 선언이 되지만

    클래스는 constructor(식별자) 메서드로 만들어주어야 한다.

     

    constructor 메서드를 살펴보면,

    this.health = a 의 의미는 다음과 같다.

    클래스는 객체를 만드는 거푸집과 같기 때문에 그 거푸집으로 찍어낼 키(key)값을 미리 마련해두고(this.health) 값(value)이 들어갈 자리(a)를 마련해두어야 한다.

     

    그리고 이렇게 거푸집이 완성되면,

    Wizard라는 클래스 거푸집으로 새로운 객체를 생성할 수 있다. ( const x = new Wizard(545, 210, 10); )

     

    15. 자기소개

    신학기가 시작되고, 아이들이 돌아가면서 자기소개를 하기로 했습니다.

    만약 입력으로 김다정이라는 이름이 주어지면 "안녕하세요. 저는 김다정입니다."라고 출력하게 해주세요.

    입출력
    
    입력 : 김다정
    출력 : 안녕하세요. 저는 김다정입니다.
    // 내 답안
    const name = prompt('이름');
    console.log('안녕하세요. 저는 ' + name + '입니다.')
    // 안녕하세요. 저는 OOO입니다.
    
    // 문제 답안
    const name = prompt('이름을 입력하세요.');
    console.log(`안녕하세요. 저는 ${name}입니다.`); 
    /*
    * es6부터는 backtick 문자열(``) 안에서 $와 중괄호로 표현식을 사용할 수 있습니다. 
    * 이를 템플릿 리터럴(Template literals)이라 합니다.
    */

    -> 템플릿 리터럴이라는게 es6 부터 생겼다고 한다.

    템플릿 리터럴

    템플릿 리터럴은 ' " 같은 통상적인 따옴표 대신 백틱(backtick) 문자 `을 사용한다.

    템플릿 리터럴은 연산자를 사용하지 않아도 간단한 방법으로 문자열을 삽입할 수 있는 기능을 제공한다. 이를 문자열 인터폴레이션(String interpolation)이라 한다.

    문자열 인터폴레이션은 #{...} 으로 표현식을 감싼다. 문자열 인터폴레이션 내의 표현식은 문자열로 강제 타입 변환된다.

     

    일반 문자열에서 줄바꿈은 허용되지 않으며 공백을 표현하기 위해서는 백슬래시(\)로 시작하는 이스케이프 시퀀스를 사용해야 한다.

    ES6 템플릿 리터럴은 일반적인 문자열과는 다르게 여러줄에 걸쳐 문자열을 작성할 수 있고 리터럴 템플릿 내의 모든 공백은 있는 그대로 적용된다.

     

    16. 로꾸거

    문장이 입력되면 거꾸로 출력하는 프로그램을 만들어 봅시다.

    입출력
    
    입력 : 거꾸로
    출력 : 로꾸거
    // 처음 내 답안
    const a = prompt('입력');
    const reverse = '';
    for(let i = 0; i < a.length; i++) {
      reverse += a[a.length - 1 - i]
    }
    console.log(reverse);
    
    // 고친 내 답안 1
    const a = prompt('입력');
    let reverse = '';
    for(let i = 0; i < a.length; i++) {
      reverse += a[a.length - 1 - i]
    }
    console.log(reverse);
    
    // 고친 내 답안 2
    const a = prompt('입력');
    let reverse = '';
    for(let i = 0; i < a.length; i++) {
      reverse = reverse.concat(a[a.length - 1 - i])
    }
    console.log(reverse);
    
    // 문제 답안
    const n = prompt('입력하세요.');
    
    const reverseString = n.split('').reverse().join('');
    /*
    * split() 메서드는 문자열을 배열로 만들어 반환하고,
    * reverse() 메서드는 배열의 순서를 반전하며,
    * join() 메서드는 원소를 모두 붙여 문자열로 반환합니다.
    */
    console.log(reverseString);

    -> 첫 내 답안을 콘솔찍어보면 이런 에러가 나온다.

    TypeError: Assignment to constant variable.

    처음에는 이 에러가 무엇인지 몰라서 허둥지둥했는데 알고보니 간단했다.

     

    에러 타입
    - ReferenceError : 존재하지 않는 변수와 함수를 호출할 때 발생.
    - TypeError : 잘못된 형식으로 자료형을 다룰 때 발생.
    - SyntaxError : 문법에 맞지 않는 코드를 작성하면 발생. 코드 실행하기 전에 에러 발생시킴.
    출처: https://anerim.tistory.com/63 [디발자 뚝딱:티스토리]

    타입에러 뒤는 상수 변수에 할당되었다는 의미인데, const는 변수 재할당이 안되기 때문에 for loop에서 문제를 일으킨것이다.

    그래서 for loop 본체에서 i 도 let으로 하는건데.. 에휴.

     

    이외에도 여러가지 풀이방법이 있어 추가했다.

    문제 답안처럼 푸는게 효율적일 것 같다.

     

    어쨌든 교훈

    1. let, const 로 어려움 겪지 않기

    2. 문자열로 지지고 볶고 하려면, 특히 순서 가지고 장난치려면 배열로 변환 후에 join 해주면 편하다!

    배열이 순서(Index)를 가졌다는 것이 아주 중요한 특징이다!

     

     

     

    댓글