2023.04.11 TIL

0

TIL

목록 보기
7/37
post-thumbnail

몸도 서서히 회복되고 있고, 떨어진 감을 보충하기 위해 최대한 많은 양의 걍의를 들었다.

오늘의 나는 무엇을 잘했을까?

저번주에 아파서 못들었던 밀린 진도를 대부분 나갔다. 집중해서 많은 것을 배운 것 같다.

오늘의 나는 무엇을 배웠을까?

  • 에러 객체

    자바스크립트는 코드 실행 도중 에러가 발생하면 자동으로 에러 정보가 담긴 에러 객체를 생성한다. 콘솔에 뜨는 에러 메세지도 에러객체의 이름과 내용이 나오는 것이다.

    • 에러객체 이름
      • Reference Error
      • Type Error
      • Syntax Error
    • 에러 객체 만들기
      const err = new TypeError('타입에러가 발생했습니다.'); //에러 객체 만들기
      
      throw err; //에러 발생시키기
  • try catch문

    try catch문을 아용하는 이유는 에러에 의해 프로그램이 전체 종료되는 것을 막기 위함이다. 예외 처리를 위해 사용한다.

    try{
    	console.log('에러 전');
    
    	const num = 10;
    	console.log(num);
    	num = 1; // const에 값 할당 에러
    	console.log(num);
    } catch (error) {     // 에러 발생후 프로그램이 종료되는 것이 아닌 catch문의 파라미터로 에러 객체가 전달됨
    	console.log(error, '에러 후');
    }
    • finally 문

      try {
        // 실행할 코드
      } catch (err) {
        // 에러가 발상했을 때 실행할 코드
      } finally {
        // 항상 실행할 코드
      }

      finally문을 붙여주는 이유는 뭘까? try catch문과 상관 없이 실행할 코드라면 아예 블록을 빠져나와 코드를 써도 항상 실행될텐데? finally 블록을 사용하지 않고 try catch문 밑에 그냥 쓴 코드는 try나 catch문의 return이 있을 때 실행되지 않는다. 하지만 finally문 안의 코드는 위에서 return을 만나도 실행된다. 이러한 이유로 열린 데이터베이스나 I/O스트림 등을 닫아주는 코드가 이곳에 위치할 수 있다.

  • 모던 자바스크립트(2)

    • forEach 메서드
      const my_arr = ['영훈', '세영', '진수'];
      
      my_arr.forEach((mem)=>{
      	console.log(`${mem}님이 입장하셨습니다.`);
      });
      
      // forEach메서드의 콜백함수 두 번째 파라미터로 index를 다룰 수 있다.
      my_arr.forEach((mem, idx) =>{
      	console.log(`${idx}: ${mem}님이 입장하셨습니다.`); 
      });
      
      // forEach메서드의 콜백함수 세 번째 파라미터로 forEach메서드를 호출한 배열을 넘길 수 있다.
      my_arr.forEach((mem, idx, arr) =>{
      	console.log(`${idx}: ${mem}님이 입장하셨습니다.`); 
      	console.log(arr);
      });
    • map 메서드 forEach와 동작이 유사하지만 메서드 호출 결과로 새로운 배열을 리턴한다.
    • filter 메서드 특정한 조건에 맞는 요소들만 필터링하여 새로운 배열을 리턴함
    • find 메서드 특정한 조건에 맞는 요소 딱 하나만 배열에서 추출하여 리턴하는 메서드, 값을 찾는 순간 반복이 종료된다. 즉 가장 먼저 조건에 부합하는 요소를 리턴하고 끝난다. (가장 앞쪽 요소가 리턴)
    • some 메서드 배열에서 특정 조건을 만족하는 요소가 하나라도 있는지 참, 거짓을 리턴하는 메서드 빈 배열이 some 메서드 호출시 false 리턴
    • every 메서드 배열의 모든 요소가 특정 조건을 만족하는지 참, 거짓을 리턴하는 메서드 빈 배열이 every 메서드 호출시 true 리턴
    • reduce 메서드
      const numbers = [1, 2, 3, 4];
      
      /**
      파라미터 설명
      1. accumulator, 누산기. 직전에 동작한 콜백함수가 리턴한 값을 전달받는 파라미터
      2. 배열의 요소
      3. 인덱스
      4. 호출한 배열
      initialAccValue: 맨 처음에 acc가 가지는 초기값
      */
      numbers.reduce((acc, el, i, arr) =>{
      	return nextAccValue;   // 다음 콜백함수의 accumulator에 전달할 값을 리턴한다.
      }, initialAccValue);
      //마지막에 호출되는 콜백함수의 리턴값이 이 reduce메서드의 최종 리턴값이 된다. 
    • sort 메서드 배열을 정렬할 수 있다. 아규먼트로 정렬 함수를 전달해주면 우리가 원하는 방식으로 정렬할 수 있다. 주의할점은 원본 배열이 정렬된다는 점이다. 따라서 원본을 보존해야 할 시에는 복사본에 대해서 sort 메서드를 호출하자.
    • reverse 메서드 단순히 배열의 순서를 뒤집는 메서드이며, sort 메서드와 마찬가지로 원본 배열이 영향을 받는다.
  • Map

    Map 자료구조는 ES2015에서 추가된 데이터 구조로, 이름이 있는 데이터를 저장한다는 점에서 객체와 비슷한 특징을 가지고 있다. 차이점은 점 표기법, 대괄호 표기법으로 프로퍼티에 접근하는 객체와 달리 전용 메서드를 통해 값을 추가하거나 조회할 수 있다.

    • map.set(key, value): key를 이용해 value를 추가하는 메소드.

    • map.get(key): key에 해당하는 값을 얻는 메소드. key가 존재하지 않으면 undefined를 반환.

    • map.has(key): key가 존재하면 true, 존재하지 않으면 false를 반환하는 메소드.

    • map.delete(key): key에 해당하는 값을 삭제하는 메소드.

    • map.clear(): Map 안의 모든 요소를 제거하는 메소드.

    • map.size: 요소의 개수를 반환하는 프로퍼티. (메소드가 아닌 점 주의! 배열의 length 프로퍼티와 같은 역할)

      // Map 생성
      const codeit = new Map();
      
      // set 메소드
      codeit.set('title', '문자열 key');
      codeit.set(2017, '숫자형 key');
      codeit.set(true, '불린형 key');
      
      // get 메소드
      console.log(codeit.get(2017)); // 숫자형 key
      console.log(codeit.get(true)); // 불린형 key
      console.log(codeit.get('title')); // 문자열 key
      
      // has 메소드
      console.log(codeit.has('title')); // true
      console.log(codeit.has('name')); // false
      
      // size 프로퍼티
      console.log(codeit.size); // 3
      
      // delete 메소드
      codeit.delete(true);
      console.log(codeit.get(true)); // undefined
      console.log(codeit.size); // 2
      
      // clear 메소드
      codeit.clear();
      console.log(codeit.get(2017)); // undefined
      console.log(codeit.size); // 0

      문자열 심벌 값만 키로 사용할 수 있는 일반 객체와는 다르게 메서드를 통해 값을 다루기에 다양한 자료형을 키로 활용할 수 있다는 장점이 있다.

  • Set

    중복을 허용하지 않는 여러 값들을 순서대로 저장하는 자료구조이다. 키-밸류 값이 아닌 값만 저장되며, 특징으로는 개별값에 한 번에 접근하는 방법이 없다. 따라서 반복문을 통해 전체 요소를 한꺼번에 다루는 순간에 개별적으로 접근할 수 있다.

    // Set 생성
    const members = new Set();
    
    // add 메소드
    members.add('영훈'); // Set(1) {"영훈"}
    members.add('윤수'); // Set(2) {"영훈", "윤수"}
    members.add('동욱'); // Set(3) {"영훈", "윤수", "동욱"}
    members.add('태호'); // Set(4) {"영훈", "윤수", "동욱", "태호"}
    
    for (const member of members) {
      console.log(member); // 영훈, 윤수, 동욱, 태호가 순서대로 한 줄 씩 콘솔에 출력됨.
    }
  • 모듈

    모듈화란, 프로그램 내 특정 기능과 관련있는 코드 조각들을 따로 파일로 관리하여 가독성과 유지 보수성을 높이는 작업을 말한다. 예를 들어 결제, 로그인, 회원가입, 장바구니 등의 서비스 내 기능들을 쪼개어 독립된 파일로 관리하는 것이 모듈화의 일종이다.

    • 모듈 파일의 조건
      • 모듈이 되는 파일은 독립적인 스코프를 가져야 한다. 이 독립된 스코프를 모듈 스코프라고 하는데, 다른 모듈들과 스코프를 공유한다면 함수, 변수의 재정의 문제나 한 모듈 안에서 의도치 않은 타 모듈의 함수를 호출하는 등 문제가 발생할 수 있기 때문이다. 모듈 파일 안에서 선언한 변수는 외부에서 자유롭게 접근할 수 없도록 막아야한다.
      • 모듈 스코프를 만들어주기 위해서 html파일에서 모듈이 된 js파일을 불러올 때 다음과 같이 type 속성에 module이라는 값을 지정해 줘야 한다.
        ...
        <body>
        	<script type="module" src="printer.js"></script>
        	...
        </body>
    • export, import
      • 한 모듈에서 선언한 변수나 함수를 타 모듈에서도 사용할 수 있게 만드는 문법. 사용하는 쪽에서는 import 문법을 써야 한다.
      • 이렇게 모듈화된 파일들끼리 export, import를 써주어 연결이 되어 있다면, html 파일에서 script태그로 모든 모듈파일들을 불러올 필요가 없다. 진입점 역할을 하는 하나의 스크립트 파일만 불러오면 된다.
    • as 키워드
      • 모듈에서 import해올 때 이름의 중복을 피하기 위해 사용하는 키워드

        import { title as printerTitle } from "./printer.js";
    • 전부 import해오기
      • * 활용 (와일드카드)

        import * as printerJS from './printer.js';
        
        printerJS.print();
    • 전부 export하기
      • 중괄호 이용

        const title = 'Codeit';
        
        function print(value){
        	console.log(value);
        }
        
        export { title, print };
    • default export
      • default 키워드가 붙은 경우 export를 하나의 대상에만 할 수 있고, export하는 모듈 파일에서 딱 한번만 사용할 수 있다.

      • export { title, print }와 같은 export를 Named export라고 한다.

      • default로 export된 값은 import해오는 곳에서 default as 사용할 이름 형식으로 접근할 수 있다. 또는 import시 중괄호를 생략하고 바로 사용할 이름을 기입해도 된다.

        /* export.js */
        export default someVariable;
        ...
        /* import.js */
        import {default as myVariable} from './export.js';
        //또는 import myVariable from './export.js';
        
  • Promise 객체

    프로미스 객체는 자바스크립트의 비동기 실행을 지원하는 문법 중 하나이다. 쉽게 생각하면 어떤 비동기적인 작업의 상태를 가지고 있는 객체라고 보면 된다.

    • 세 가지 상태
      • pending: 진행중
      • fulfilled: 성공
      • rejected: 실패
    • Promise 객체의 then() 메서드
      • 프로미스 객체의 상태가 pending에서 fulfilled 상태가 될 때 실행할 콜백을 등록해주는 메서드

      • 프로미스 객체의 상태가 fulfilled상태가 되면 담당하던 비동기적 작업의 성공 결과 또한 가지게 된다. 이 작업 성공의 결과가 then 메서드를 통해 등록한 콜백의 파라미터로 넘어가게 된다. (아래에서는 response라는 파라미터)

        fetch('https://jsonplaceholder.typeicode.com/users')
        	.then((response)=>{response.text()}); // fetch가 리턴하는 프로미스 객체의 상태가 fulfilled가 되면 실행할 콜백함수를 then 메소드로 등록!

        Untitled

    • Promise Chaining
      • then메서드는 또 다시 해당 then에서드가 등록했던 콜백함수의 작업(비동기적)에 대한 프로미스 객체를 리턴한다. 그래서 then메서드 뒤에 다른 then메서드를 이어 붙일 수 있다. 이렇게 then메서드들을 이어 붙이는 것을 Promise chaining이라 한다. 비동기적인 작업들을 순차적으로 깔끔하게 정리하고자 할 때 사용하는 기술이다.
      • then메서드가 등록한 콜백함수는 프로미스 객체를 리턴할 수 있고, 일반 값을 리턴할 수도 있다. 경우에 따라 then메서드가 리턴한 프로미스 객체의 상태가 다르다.
      • 콜백함수가 프로미스 객체를 리턴하는 경우, then메서드가 리턴하는 프로미스 객체와 상태가 동일하게 유지된다. 콜백함수가 하는 작업에 따라 두 프로미스가 fulfilled, rejected상태를 가질 수 있다. 반면에 콜백함수가 일반 값을 리턴하는 경우, then메서드가 리턴하는 프로미스의 상태는 바로 fulfilled상태가 되고, 콜백함수가 리턴하는 그 일반 값을 작업 성공 결과로 가지게 된다.
    • Promise.all()
      • 파라미터로 promise객체 배열을 받으며, 받은 모든 promise객체의 상태가 pending에서 fulfilled가 될 때까지 기다린다. then메서드처럼 새로운 promise 객체를 리턴한다. all메서드가 받았던 배열의 모든 요소가 fulfilled가 되면 all메서드가 리턴하는 프로미스 객체 또한 fulfilled상태가 된다.
      • all메서드가 리턴하는 프로미스 객체는 받은 배열의 각 프로미스 객체의 성공 결과로 이루어진 배열을 가진다.
      • 하나라도 rejected 상태가 되면 all메서드가 반환하는 프로미스 객체의 상태도 rejected가 된다.
    • Promise.race()
      • all메서드와 마찬가지로 프로미스 객체의 배열을 받는다. 하지만 그 요소들 중 가장 먼저 fulfilled 상태, 또는 rejected상태가 된 객체와 동일한 상태와 결과를 가지는 프로미스 객체를 리턴한다.
  • async/await

    async await 문법은 프로미스 객체를 조금 더 세련되게 다룰 수 있는 문법이다. 다음 코드를 보자.

    async function fetchAndPrint(){
    	const response = await fetch('someurl');
    	const result = await response.text();
    	console.log(result);
    }
    
    console.log(1);
    fetchAndPrint();
    console.log(2);

    async 키워드가 붙은 함수 안에서만 await키워드를 사용할 수 있다. async 키워드를 붙인 함수는, 함수 내부에 비동기적인 코드가 포함되어 있다는 선언과도 같다. 그리고 await 키워드는 그 함수 내의 비동기 코드(프로미스를 리턴하는 부분) 앞에 붙는다. await가 붙은 문장은 해당 프로미스가 fulfilled 상태가 될 때까지 기다리게 된다.

    또한, async 함수가 호출되어 함수 내부가 실행될때 await 키워드를 만나면 다시 함수 호출부 이후로 가서 동기적인 코드들을 먼저 실행한다. 동기적 코드들이 모두 실행되고 나면 다시 함수 내부로 들어가서 await를 기다리게 된다.

    • async await을 쓰는 이유

      async await은 사실 구문 자체가 기존 promise 객체를 사용하는 체이닝 코드를 개발자가 더 편하게 작성할 수 있도록 하고 가독성을 높이기 위해서 만들어진 syntactic sugar와도 같다. promise.then().then().then()방식으로 이어 붙이는 코드보다 원래 전통적인 방식으로 코드를 한 줄 한 줄 쓰는 것이 읽기도 편하고 익숙한 방법이기 때문이다.

    • rejected 상태가 된 promise 객체의 처리

      async await 구문에서는 try catch문으로 rejected된 프로미스를 처리한다.

      async function fetchAndPrint(){
      	try{
      		const response = await fetch('someurl');
      		const result = await response.text();
      		console.log(result);
      	}
      	catch(err){
      		console.log(err);
      	}
      }
    • Async 함수는 항상 프로미스 객체를 리턴한다

      • async 함수는 then메서드처럼 항상 프로미스 객체를 리턴한다. 그리고 우리가 async 함수에 리턴문을 어떻게 작성하는지에 따라 리턴하는 프로미스 객체의 상태와 저장하고있는 결과값이 달라진다.
      • 값을 리턴하는 경우
        • promise 리턴시 async함수가 리턴하는 프로미스는 동일한 상태와 결과값을 가진다.
        • 일반 값 리턴시 async함수가 리턴하는 프로미스는 fulfilled상태이면서 리턴한 일반값을 작업 성공 결과로 가진다.
      • 아무 값도 리턴하지 않는 경우
        • async 함수가 리턴하는 프로미스는 fulfilled상태이면서 작업 성공 결과로 undefined를 가진다.
      • async함수 내부에 에러 발생 시
        • async 함수가 리턴하는 프로미스는 rejected 상태이면서 해당 에러 객체를 작업 실패 정보로 가진다.
  • 자바스크립트 객체 지향 프로그래밍

    객체만들기

    • 객체 리터럴 방식

      const user = {
      	name: "Kenny",
      	age: 27,
      } // 객체 리터럴 -> 객체를 나타내는 문자열
    • factory function 사용 방식

      객체 관련 정보를 파라미터로 받아서 객체를 만들어 리턴하는 함수를 작성하는 방법

      function createUser(name, age){
      	const user = {
      		name: name,
      		age: age,
      	};
      	return user;
      }
      
      const user1 = createUser('Kenny', 27);
    • Contructor function 사용 방식

      생성자 함수를 만들어 바로 바로 객체들을 찍어내는 방법. 호출시 new 키워드를 붙여줘야 정상 작동한다.

      function User(name, age){
      	this.name = name;
      	this.age = age;
      }
      
      const user1 = new User("Kenny", 27);
    • 클래스 사용 방식

      class User {
      	constructor(name, age) {
      		this.name = name;
      		this.age = age;
      	}
      }
      
      const user = new User('Kenny', 27);
  • 객체 지향의 4가지 특징

    • 추상화

      추상화는 어떤 구체적인 존재를 우리가 원하는 방향으로 간략화해서 나타내는 것이다. 객체 지향 프로그래밍에서는 추상화를 객체의 공통적인 속성과 기능을 추출하여 정의하는 행위를 통해 이루어낸다.

    • 캡슐화

      캡슐화는 객체의 특정 프로퍼티에 직접 접근하지 못하도록 막는 것이다. 예를 들어 user 객체의 email 프로퍼티를 누군가 함부로 바꾸거나 조회할 수 없도록 setter, getter메서드를 클래스 내부에 정의하여 외부에 노출되지 않게 캡슐에 담는 듯한 행위를 하는 것이다.

    • 상속

      클래스간 계층 구조를 가진다. 자식 클래스는 부모 클래스의 프로퍼티와 메서드를 상속받기 때문에 자식 클래스를 만들 때 전부 따로 다시 써줄 필요가 없다. 상속으로 인해 코드의 재사용성이 높아지게 된다.

    • 다형성

      다형성은 많은 형태를 가진 성질이란 뜻이며, 상속받은 클래스들의 메서드나 프로퍼티가 각 클래스마다 조금 다른 형태를 띨 수 있다는 뜻이다. 정확하게 말하면 부모 클래스로부터 물려받은 메서드를 오버라이딩(재정의)하여 사용할 수 있다는 뜻이다. 다형성을 활용하면 다른 종류의 객체에 있는 같은 이름의 메서드를 반복문 등으로 간결하게 호출할 수 있다.

오늘의 나는 어떤 어려움이 있었을까?

내용이 많아서 심화학습이 필요한 부분과 그렇지 않고 빨리 넘어갈 부분을 구분하는데 어려움이 있었다. 글을 읽고 강의를 들으면 일단은 다 이해가 된것 같은데 막상 해보면 분명 제대로 이해하지 못한 부분이 있을 것이다.

내일의 나는 무엇을 해야할까?

  • 자료구조 공부 시작
  • 비동기 (Promise, async, await) 복습
  • 자바스크립트 객체 지향프로그래밍 관련 추가 영상 찾아 듣기

0개의 댓글