본문 바로가기

JavaScript

JavaScript 기본 - 응용 개념 정리

React와 Nodejs 학습을 위해 JavaScript를 다시 보고 있다.

Falsy

자바스크립트 엔진은 boolean 타입이 아닌 값을 Truthy, Falsy로 구분한다.

조건문이나 반복문에서 Truthy값은 true, Falsy값은 false로 암묵적 형 변환이 일어난다. Falsy 이외의 모든 값은 Truthy이다. falsy 값을 파악해보자.

  • null
  • undefined
  • 숫자 0
  • 숫자 -0
  • NaN
  • "" (빈문자열)
let a = "";
if(a){
  console.log("TRUE");
} else{
  console.log("FALSE");
}
// 출력값 : FALSE

이를 이용해서 null과 undefined에 대한 예외처리를 할 수 있다.

if(!매개변수) -> 매개변수가 null이거나 undefined라면 true가 됨

const getName = (person) =>{
  if(!person){ // false + NOT => True
    return "객체가 아닙니다";
  }
  return person.name;
}

let person;
const name = getName(person);
console.log(name); // 객체가 아닙니다

삼항연산자와 응용하기

let a;
const result = a? true : false;
console.log(result); // false

단락 회로 평가

왼쪽에서 오른쪽으로 이동하는 논리 연산자(&&,||,!)의 특성을 이용한 문법.
console.log(false && true;
&& 는 앞의 값이 false 이면 여기서 연산 종료(둘 다 true가 되야하기 때문)
console.log(true || false)
|| 는 앞의 갚이 true인 경우 연산 종료 (하나만 true 여도 true 반환)

truthy, falsy 와 단락 회로 평가 응용

const getName1 = (person) => {
  if (!person) {
    return "객체가 아닙니다";
  }
  return person.name;
};

이를 아래와 같이 변경할 수 있다.

const getName2 = (person) => {
  const name = person && person.name; // person이 truthy -> name에 person.name 대입
  return name || "객체가 아닙니다"; // name이 truthy -> name 바로 리턴
};

let person = {name: "이정환"};
const name = getName2(person);
console.log(name); // 이정환

/* 값이 falsy인 경우 */

const getName2 = (person) => {
  const name = person && person.name; // person이 falsy -> null 바로 대입
  return name || "객체가 아닙니다"; // 앞에가 falsy -> 뒤로 넘어와서 truthy반환
};

let person = null;
const name = getName2(person);
console.log(name); // 객체가 아닙니다

비구조화 할당

배열이나 객체 속성을 해체하여 개별 변수에 값을 담는 표현식이다.

기본값 부여 시 = 연산자를 사용해준다


let [one,two,three, four='four'] = ["one1","two2","three3"]; // four에 디폴트값 부여해줌(원래는 값이 없어서 undefined)
console.log(one,two,three, four); // 출력 : one1 two2 three3 four 

swap도 활용할 수 있다.

a와 b에 배열의 0번인덱스, 1번 인덱스를 할당한다.

// swap 활용

let a = 10;
let b = 20;
[a,b] = [b,a];
console.log(a,b); // 20 10
console.log(a); // 20

객체의 비구조화 할당

객체는 배열과 달리 key값으로 접근한다.

let object  = {one:"one1",two:"two2",three:"three3",name:"이정환"};

// let one = object.one;
// let two = object.two;
// let three = object.three;

let {name, one, two, three} = object;

console.log(one, two, three, name);

key값 말고 다른 변수 이름으로 할당받고 싶을때:

key값:사용할 변수이름

let {name:myName, one, two, three} = object;

console.log(one, two, three, myName);

기본값 부여 시 = 연산자 사용

let {name:myName, one, two, three, abc="four"} = object;

console.log(one, two, three, myName,abc);

Spread 연산자 ...

객체의 값을 새로운 객체에 펼쳐주는 역할.


const cookie = {
  base: "cookie",
  madeIn: "korea"
};

const chocochipCookie = {
  base: "cookie",
  madeIn: "korea",
  toping: "chocochip"
};

const blueberryCookie = {
  base: "cookie",
  madeIn: "korea",
  toping: "blueberry"
};
const strawberryCookie = {
  base: "cookie",
  madeIn: "korea",
  toping: "strawberry"
}

중복되는 값을 ... 연산자를 사용하면 위와 같은 코드가 된다

const cookie = {
  base: "cookie",
  madeIn: "korea"
};

const chocochipCookie = {
  ...cookie,
  toping: "chocochip"
};

const blueberryCookie = {
  ...cookie,
  toping: "blueberry"
};
const strawberryCookie = {
  ...cookie,
  toping: "strawberry"
};

배열에도 사용할 수 있다.
배열에 spread 연산자를 사용하면 concat메서드와 달리 중간에 하나 요소를 더 추가해서 합칠 수 있음.

const noTopingCookies = ["촉촉한쿠키", "안촉촉한쿠키"];
const topingCookies = ["바나나쿠키", "블루베리쿠키", "딸기쿠키", "초코칩쿠키"];

const allCookies = [...noTopingCookies, "함정쿠키", ...topingCookies];
console.log(allCookies); // ["촉촉한쿠키", "안촉촉한쿠키", "함정쿠키", "바나나쿠키", "블루베리쿠키", "딸기쿠키", "초코칩쿠키"]

Promise - 콜백 지옥에서 벗어나게 해주는 기능

비동기 작업이 가질 수 있는 3가지 상태

Pending : 진행중이거나 시작할 수 없는 문제가 발생한 상태
Fulfilled : 성공(resolve된 상태)
Rejected : 실패(reject된 상태)

Promise 사용 전

function isPositive(number,resolve,reject){
  setTimeout(()=>{
    if(typeof number === 'number'){
      // 성공
      resolve(number >=0?"양수":"음수");
    } else{
      reject("주어진 값이 숫자형 값이 아닙니다");
    }
  },2000);
};

 isPositive([],(res)=>{
   console.log("성공적으로 수행됨 : ",res)
 },(err)=>{console.log("실패하였음 :",err)});

Promise 사용 후(then 콜백함수, catch 콜백함수 사용)

function isPositiveP(number){
  const executor = (resolve,reject) =>{
    setTimeout(()=>{
      if(typeof number === 'number'){
        console.log(number);
        // 성공
        resolve(number >=0?"양수":"음수");
      } else{
        reject("주어진 값이 숫자형 값이 아닙니다");
      }
    },2000);
  };

  const asyncTask = new Promise(executor);
  return asyncTask;
}

const res = isPositiveP([]);
res
  .then((res)=>{
    console.log("작업성공:",res);
  })
  .catch((err)=>{
    console.log("작업실패:",err);
  });

콜백지옥 예시

function taskA(a, b, cb) {
  setTimeout(() => {
    const res = a + b;
    cb(res);
  }, 3000);
}

function taskB(a, cb) {
  setTimeout(() => {
    const res = a * 2;
    cb(res);
  }, 1000);
}

function taskC(a, cb) {
  setTimeout(() => {
    const res = a * -1;
    cb(res);
  }, 2000);
}

taskA(4, 5, (a_res) => {
  console.log("A RESULT :", a_res);
  taskB(a_res, (b_res) => {
    console.log("B RESULT :", b_res);
    taskC(b_res, (c_res) => {
      console.log("C RESULT :", c_res);
    });
  });
});

console.log("코드 끝");

Promise를 사용하면? : then chaining

function taskA(a,b){
  return new Promise((resolve, reject)=>{
    setTimeout(()=>{
      const res = a+b;
      resolve(res);
    },3000);
  });
}

function taskB(a){
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      const res = a*2;
      resolve(res);
    },1000);
  });
}

function taskC(a){
  return new Promise((resolve,reject)=>{
    setTimeout(()=>{
      const res = a*-1;
      resolve(res);
    },2000);
  });
}

taskA(5,1).then((a_res) => {
  console.log("A RESULT:",a_res);
  return taskB(a_res);
}).then((b_res)=>{
  console.log("B RESULT: ",b_res);
  return taskC(b_res);
}).then((c_res)=>{
  console.log("C RESULT:",c_res);
});

Promise를 사용하면 중간에 다른 로직도 사용할 수 있음.

const bPromiseResult = taskA(5, 1).then((a_res) => {
  console.log("A RESULT:", a_res);
  return taskB(a_res);
});

console.log("중간에 들어왔어욥");

bPromiseResult
  .then((b_res) => {
    console.log("B RESULT: ", b_res);
    return taskC(b_res);
  })
  .then((c_res) => {
    console.log("C RESULT:", c_res);
  });

async : promise를 더 쉽게 사용할 수 있도록 도와줌

async를 함수에 붙이면 반환값이 Promise가 됨.

async function helloAsync() {
  return "hello Async";
}

helloAsync().then((res)=>{
  console.log(res);
})

await : 함수를 동기적 실행

함수 호출 시 await 을 붙여주면 함수를 동기적으로 실행한다.
async 내에서만 사용이 가능하다

async function helloAsync() {
  return delay(3000).then(()=>{
    return "hello Async";
  })
}

helloAsync().then((res)=>{
  console.log(res);
})

위와 같은 코드

async function helloAsync() {
  await delay(3000); // 동기 실행(끝날때까지 blocking)
  return "hello Async";
}

'JavaScript' 카테고리의 다른 글

JavaScript의 메모리 구조  (0) 2024.02.01
JavaScript 기본 다시보기  (0) 2024.01.31
null병합연산자 ??  (0) 2023.11.22