본문 바로가기
교육, 대외활동/유데미 프론트엔드 캠프

[유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 - 사전직무교육 1주차 학습 회고 -(1) 자바스크립트 문법

by daami 2024. 11. 17.

 

🍀 What I Learned this week

📌 자바스크립트 문법

  🧷 자바스크립트는 프로토타입 기반 언어!

  🧷 배열

  🧷 this의 의미

  🧷 콜백함수와 비동기 함수, 에러 핸들링

  🧷 클래스

📌 React 프로젝트: Vite + Shadcn UI를 활용, tailwind.css 사용 

  🧷 오픈 날씨 API를 활용한 리액트 대시보드 만들기

  🧷 이미지 오픈 API를 통해 이미지 정보 조회 사이트 만들기

📌 타입스크립트 문법

 

 

📌 Javascript 문법

 

 

🧷  자바스크립트는 프로토타입 기반 언어이다.

자바스크립트는 클래스라는 개념이 없다. 기존의 객체를 복사하여 새로운 객체를 생성하는 프로토타입 기반의 언어이다. [확장성]

//const fruits = ["사과", "바나나", "체리"]; -> 리터럴 방식으로 배열 만듦
//사실 생성자 함수를 사용한 과정이 내포되어있음! 간결화 한것

const fruits = new Array("사과", "바나나", "체리");
//데이터(배열) 인스턴스를 생성해서 fruits에 할당한 것
//프로토타입이기 때문에, fruits는 배열로 작용하여 배열 메소드들을 쓸 수 있다!!

//프로토타입 활용 => Array의 프로토타입에 새로운 메서드 등록
Array.prototype.getName = function () {
    console.log(this); //Array를 참조하기 때문에 그대로 나옴
};
fruits.getName(); //["사과", "바나나", "체리"]

 

즉, 프로토타입은 new키워드를 이용한 생성자 함수에서 반환된 결과이다. 이를 "인스턴스를 생성한다."고 한다.

 

 

 

🧷  배열

구조 분해 할당 

const user = {
    name: "Riku",
    password: "0000",
    age: 21,
}

function getUser(){
    const [name, password] = user
}

 

객체 내 데이터가 많을 때, 필요한 데이터를 뽑고 싶을 때 구조분해 할당은 유용하다.

*react의 prop에서 활용

 

나머지 매개변수 (Rest parameters / ....)

함수에 전달되는 가변 개수의 인자를 배열로 받을 수 있게 해준다.

 

<주요 특징>

  • 배열 인스턴스: 나머지 매개변수는 Array 인스턴스이므로 sortmapforEachpop 등의 메서드를 직접 적용할 수 있다.
  • 유연성 : 함수 호출 시 전달되는 인자의 개수에 상관없이 사용할 수 있어 유연하다.

<제한 사항>

  •  마지막 매개변수만 나머지 매개변수로 설정할 수 있다. 
  •  함수 정의에는 하나의 ...만 존재할 수 있다. 
  • 기본값 지정 불가
function sum(...theArgs) {
  let total = 0;
  for (const arg of theArgs) {
    total += arg;
  }
  return total;
}

console.log(sum(1, 2, 3));
// Expected output: 6

 

** 전개 연산자와 모양은 같지만 쓰임은 다르다!!

  • 나머지 매개변수: 여러 값을 하나의 배열로 모은다.
  • 전개 연산자: 배열이나 객체를 개별 요소로 펼친다.  ➡️ 배열이나 객체를 다른 배열/객체에 삽입하거나 함수 인수로 전달할 때 사용
// 전개 연산자
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]

 

Array 메서드: reduce()

reduce() 메서드는 배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환한다.

총 합을 구할 때 많이 쓴다.

 

 

 

🧷 this의 의미

  • 일반 함수의 this는 호출 위치에서 정의된다.
  • 화살표 함수의 this는 자신이 선언된 함수(렉시컬) 범위에서 정의된다. → 즉, 상위 스코프
    • 렉시컬: 함수가 동작할 수 있는 유효한 범위
const user = {
    firstName: 'Mina',
    lastName: 'Lee',
    age: 25,
    getFullName: function() {
        return `${this.firstName} ${this.lastName}` ; //호출위치: user
    }
}

const user2 = {
    firstName: 'Mina',
    lastName: 'Lee',
    age: 25,
    getFullName: () =>  {
        return `${this.firstName} ${this.lastName}` ; //undefined
    }//렉시컬 내에 user2가 없음!!! getFullName이 선언된 함수가 없음
}

 

 

🧷 콜백함수와 비동기 프로그래밍, 에러 핸들링

콜백 함수

함수가 실행될 때, 인수/인자로 들어가는 또 다른 함수

const c = (callback) => {
    // callback은 함수 데이터이므로 소괄호를 열고, 닫아서 실행시킬 수 있다.
    console.log("C");
    callback(); // D 실행
};
const d = () => {
    console.log("D");
};
c(d); d: 콜백, 콜백 함수라고 부릅니다.
  • 비동기 함수에서 발생하는 문제점
const sum = (a, b) => {
    setTimeout(() => {
        return a + b; // callback 함수의 return
    }, 1000);
};
console.log(sum(1, 2)); // undefined
console.log(sum(3, 7)); // undefined

 

setTimeout은 비동기함수여서, setTimeout이 결과를 반환하기 전에 sum함수가 먼저 끝나버린다. sum함수의 return값이 없으므로, ㅊconsole에 undefined가 출력된다.

  • 콜백패턴으로 문제점 해결하기
const sum2 = (a, b, c) => {
    setTimeout(() => {
        c(a + b); //a+b가 value값으로 들어감
    }, 1000);
};

sum2(1, 2, (value) => { 
    console.log(value);
});

setTimeout은 1초 후에 계산된 값을 콜백 함수 c로 전달한다.

따라서 c는 비동기 작업이 끝난 후에 호출되므로, console에 계산된 값이 출력된다.

 

비동기 프로그래밍

  • 순차적으로 실행되지 않는 것
  • 이벤트리스닝도 비동기 로직이다. (이벤트가 발생했을 때 실행하기 때문)
  • 콜백 패턴 : 비동기 프로그래밍에서 특정 작업이 완료된 후 실행할 함수를 전달하는 방식. 비동기 함수가 완료된 후 호출되는 "콜백 함수"를 지정하여 이후 처리할 작업을 정의한다.
    • 콜백 지옥을 주의하자!
const a = (callback) => {
    setTimeout(() => {
        console.log(1);
        callback();
    }, 1000);
};
const b = (callback) => {
    setTimeout(() => {
        console.log(2);
        callback();
    }, 1000);
};
const c = (callback) => {
    setTimeout(() => {
        console.log(3);
        callback();
    }, 1000);
};
const d = () => console.log(4);

/* 콜백 패턴
 코드를 점점 들여쓰기 방식으로 작성하게 되는데 이를 '콜백 지옥'이라고 한다.
 */
a(() => {
    b(() => {
        c(() => {
            d();
        });
    });
});

 

➡️ 해결법: Promise 객체 쓰기

//콜백 방식
const a = (callback) => {
    setTimeout(() => {
        console.log(1);
        callback();
    }, 1000);
};
const b = () => console.log(2);

a(() => {
    b();
});


//프로미스 방식
const c = () => {
    /** callback을 대신해서 매개변수resolve를 callback이 실행되는 부분에서 대신해서 실행시켜준다. */
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(3);
            resolve();
        }, 1000);
    });
};

const d = () => console.log(4);
/** Promise에서 만들어진 인스턴스에서는 then이라는 메서드를 이어서 체이닝 형식으로 활용할 수 있다. */
c().then(() => {
    d();
});

/*반환값이 존재(resolve가 결과값을 반환함 -> Promise객체값이 된다.)하므로 이렇게 쓸 수 있음 */
c().then(d)
  • resolve: 비동기 작업이 성공적으로 완료되었을 때 호출되는 함수
  • reject: 비동기 작업이 실패했을 때 호출되는 함수

 

  • async-await : Promise를 반환하는 함수 안에서 사용가능하다. 이를 사용하면 비동기 로직을 동기 코드 처럼 보이게 하여, then을 여러번 사용하는 것보다 가독성을 높여주는 특징이 있다.
//위의 코드 리팩토링
const fn = async () => {
    await c(); // c의 실행을 기다렸다가 d실행. 즉 Promise가 반환된 후에 console.log 실행
    d();
};

fn();

 

에러 핸들링

  • 콜백 패턴에서
const delayAdd = (idx, callback, error) => {
    setTimeout(()=> {
        if (idx > 10){
            error(`${idx}는 10보다 클 수 없습니다.`);
            return;
        }
        console.log('idx: ',idx);
        callback(idx + 1);
    }, 1000);
};

delayAdd(4, (res)=> console.log(res), (error) => console.log(error)); //idx: 5

delayAdd(10, (res)=> console.log(res), (error) => console.log(error));
//13은 10보다 클 수 없습니다. -> 에러가 발생했을때의 로직을 따로 작성했으므로, 에러가 처리된다.
  • 프로미스로 처리
const newDelayAdd = (idx) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (idx > 10) {
        reject(`${idx}는 10보다 클 수 없습니다.`);
        return;
      }
      console.log('idx: ', idx);
      resolve(idx + 1);
    }, 1000);
  });
};


//then으로 처리
newDelayAdd(9)
  .then((res) => console.log(res)) //10
  .catch((err) => console.log(err))
  .finally(() => console.log('done')); //finally: 무조건 실행
  
  
//try-catch문으로 처리 (async-await구문 사용할 때)
const wrap = async() => {
    try {
        const res = await newDelayAdd(9);
        console.log(res);
    } catch(error) {
        console.error(error);
    } finally {
        console.log('done');
    }
};
wrap();

 

 

 

🧷 클래스

 

자바스크립트의 클래스 문법은 기존에 가지고 있었던 프로토타입 방식을 내장한 새로운 문법이다.

  • getter와 setter
class User {
    constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
      this.fullName = this.getFullName();
    }
  
    getFullName() {
      return `${this.firstName} ${this.lastName}`;
    }
  }

  const user1 = new User("Mina", "Lee");
  user1.firstName = "Rena"; 
  console.log(user1.fullName); //Mina Lee
  //생성자함수로 최초만 만들어지고, 그다음부터 firstName과 lastName이 바뀌더라도 전혀 변화X
  //이 부분을 보완하기 위해 메서드 활용

  console.log(user1.getFullName()); //Rena Lee


  //getter,setter 활용
  class NewUser {
    constructor(firstName, lastName) {
      this.firstName = firstName;
      this.lastName = lastName;
    }

    get fullName() { //함수이므로 다양한 로직 추가 가능
      return `${this.firstName} ${this.lastName}`;
    }
    set fullName(value){
        console.log(value);
        this.firstName = value.split(" ")[0];
        this.lastName = value.split(" ")[1];
    }
  }

  const user2 = new NewUser('Mina', 'Lee');
  user2.firstName = 'Jane';
  console.log(user2.fullName); //Jane Lee

  user2.lastName = 'Kim';
  console.log(user2.fullName); //Jane Kim

 

 

 

출처:https://blog.naver.com/weartstudio/ , MDN

 

——————————————————————————

본 후기는 [유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 과정(B-log) 리뷰로 작성 되었습니다.