JavaScript 는 “JavaScript 엔진”에 의해 작동된다.

“JavaScript 엔진” 은 브라우저에 기본 탑재되어 있다. 따라서 우리는 크롬, 사파리와 같은 웹 브라우저를 이용해 간단한 JavaScript 코드를 직접 실행해 볼 수 있다.

변수와 상수

  • var: 재선언 가능, 재할당 가능 (스코프와 호이스팅 문제로 사용 지양)
  • let: 재선언 불가능, 재할당 가능
  • const: 초기화 필수, 재선언 및 재할당 불가능

호이스팅(끌어올리는) : 호출문보다 아래에 작성된 선언문들을 상단으로 끌어올려 실행시켜줌

타입

  • Number : 숫자값 , 연산 계산 가능, Infinity, -Infinity, NaN 값 포함
  • String : 문자열 값, 따옴표로 표현, 덧셈 연산 지원, 변수의 값 동적으로 표현 가능 : ${name} (템플릿 리터럴 문법)
  • Boolean : true, false 상태 표현
  • Null : 아무런 값도 담겨 있지 않음 표현
  • Undefined : 변수를 선언하고 값을 할당하지 않은 상태

형변환

  • 묵시적 형 변환 : 자바스크립트 엔진이 알아서 형변환
  • 명시적 형 변환 : 직접 형 변환 명시
let num = 10;
let str = "20";
console.log(num + str); // 1020

let str1 = "20";
let strToNum = Number(str1);
console.log(strToNum); //20

let str2 = "10개";
let strToNum2 = parseInt(str2);
console.log(strToNum2); //10

연산자

  • null 뱐합 연산자 : ?? null, defined가 아닌 값을 찾아내는 연산자.
let var1;
let var2 = 10;
let var3 = 20;

let var4 = var1 ?? var2;
console.log(var4); //10
  • type of 연산자 값의 타입을 문자열로 반환하는 기능을 하는 연산자
let var7 = 1;
let t1 = typeof var7;
console.log(t1); // number
  • 삼항 연산자
let var8 = var7 % 2 === 0 ? "짝수" : "홀수";
console.log(var8); // 홀수

조건문

  • if
let num = 10;

if (num > 10) {
  console.log("num은 10 이상입나다.");
} else if (num > 5) {
  console.log("num은 5 이상입나다.");
} else {
  console.log("num은 5 미만입나다.");
}
  • switch
let animal = "cat";

switch (animal) {
  case "cat": {
    console.log("고양이");
    break;
  }
  case "dog": {
    console.log("강아지");
    break;
  }
  case "bear": {
    console.log("");
    break;
  }
  default: {
    console.log("알 수 없는 동물");
  }
}

반복문

  • for
for (let idx = 0; idx < 5; idx++) {
  console.log(idx);
}

함수

  • 함수 표현식
// 함수 선언문
function funcA() {
  console.log("funcA");
}

let varA = funcA;

varA();

let varB = function funcB() {
  console.log("funcB");
};

varB();

// 익명함수
let varc = function () {
  console.log("funcC");
};

varc();
function funcA() {
  console.log("funcA");
}

let varA = funcA;

varA();

varB(); // 호이스팅 안됨

varc(); // 호이스팅 안됨

let varB = function funcB() {
  console.log("funcB");
};

let varc = function () {
  console.log("funcC");
};
  • 화살표 함수
let vard = () => 1;

console.log(vard()); // 1

let vare = (value) => {
  console.log(value);
  return value + 1;
};

vare(11);

콜백함수(Callback Function)

자신이 아닌 다른 함수에, 인수로써 전달된 함수를 의미함

function main(value) {
  value();
}

function sub() {
  console.log("I am sub");
}

main(sub);
function main(value) {
  value();
}

main(() => {
  console.log("I am sub");
});
  • 콜백함수 활용
function repeat(count) {
  for (let idx = 0; idx <= count; idx++) {
    console.log(idx);
  }
}

function repeatDouble(count) {
  for (let idx = 0; idx <= count; idx++) {
    console.log(idx * 2);
  }
}

function repeatTriple(count) {
  for (let idx = 0; idx <= count; idx++) {
    console.log(idx * 3);
  }
}
function repeat(count, callback) {
  for (let idx = 0; idx <= count; idx++) {
    callback(idx);
  }
}

repeat(
  5,
  (repeatDouble = (idx) => {
    console.log(idx * 2);
  })
);

repeat(
  5,
  (repeatTriple = (idx) => {
    console.log(idx * 3);
  })
);

스코프

변수나 함수에 접근하거나 호출할 수 있는 범위

  • 전역 스코프 : 전체 영역에서 접근 가능

  • 지역 스코프 : 특정 영역에서만 접근 가능

객체

  • 객체 생성

    • let obj1 = new Object(); : 객체 생성자 이용
    • let obj2 = {}; : 객체 리터럴 이용
  • 객체 프로퍼티

let person = {
  name: "yun",
  age: 100,
  email: "yun@gmail.com",
};

// 프로퍼티 수정
person.name = "YUN";
// 프로퍼티 삭제
delete person.email;
// 프로퍼티 존재 유무 확인
email in person;

배열

여러개의 값을 순차적으로 담을 수 있는 자료형

  • 배열 생성자 : let arrA = new Array();
  • 배열 리터럴 : let arrB = []

Truthy & Falsy

JavaScript 에서는 상황에 따라 참, 거짓이 아닌 값도 참, 거짓으로 판단한다.

  • Falsy
let f1 = undefined;
let f2 = null;
let f3 = 0;
let f4 = -0;
let f5 = NaN;
let f6 = "";
let f7 = 0n;

// if(f1) => false
  • Truthy 7가지의 Falsy 한 값들을 제외한 값 들

단락 평가(Short-circuit Evaluation)

function returnFalse() {
  console.log("False 함수");
  return false;
}

function returnTrue() {
  console.log("True 함수");
  return true;
}

// False 함수
//  false
console.log(returnFalse() && returnTrue());

returnFalse() 가 False 이므로 returnTrue()에 접근안함 => 단락평가가 이루어짐

  • 단락평가 활용
let person = {
  name: "yun",
  age: 100,
  email: "yun@gmail.com",
};

function printName(person) {
  const name = person && person.name;
  console.log(name || "person 값 없음");
}

printName(person);
  • Truty   Truthy -> 앞에 있는 Truthy 한 값 반환
  • Truty && Truthy -> 뒤에 있는 Truthy 한 값 반환

구조 분해 할당

  • 배열의 구조 분해 할당
let arr = [1, 2, 3];

let [one, two, three] = arr;
  • 객체의 구조 분해 할당
let person = {
  name: "yun",
  age: 100,
  email: "yun@gmail.com",
};

let { name, age, email } = person;
console.log(name, age, email); // yun 100 yun@gmail.com
let { age: myAge, email } = person;

console.log(myAge, email); // 100 'yun@gmail.com'
  • 함수의 매개변수
const func = ({ name, age, email }) => {
  console.log(name, age, email);
};

func(person);

Spread 연산자와 Rest 매개 변수

  • Spread 객체나 배열에 저장된 여러개의 값을 개별로 흩뿌려주는 역할
let arr1 = [1, 2, 3];
let arr2 = [4, ...arr1, 5, 6];

console.log(arr2); // [4, 1, 2, 3, 5, 6]
let obj1 = {
  a: 1,
  b: 2,
};

let obj2 = {
  ...obj1,
  c: 3,
  d: 4,
};

console.log(obj2); // {a: 1, b: 2, c: 3, d: 4}
funcA = (a, b, c) => {
  console.log(a, b, c);
};

funcA(...arr1); // 1, 2, 3
  • Rest 나머지 매개변수

  • rest 뒤에 추가적인 매개변수 추가 불가

function funcB(...rest) {
  console.log(rest); // 배열에 모든 값 저장
}

funcB(...arr1); // [1, 2, 3]

function funcC(first, ...rest) {
  console.log(first);
  console.log(rest); // 첫번쨰 원소를 제외한 값
}

funcC(...arr1);

// 1
// [2, 3]

원시타입 vs 객체타입

원시타입과 객체타입이 값이 저장되거나 복사되는 과정이 서로 다르다.

  • 원시타입 : 값 자체로써 변수에 저장되고 목사 된다 (Number, String, Boolean …)

불변값이다 (메모리 값 수정 안됨)

let p1 = 1;
let p2 = p1;
p2 = 2;

console.log(p1, p2); //1, 2
  • 객체타입 : 참조값을 통해 변수에 저장되고 복사된다 (Object, Array, Function …)

가변값이다(메모리값이 수정된다)

let sample = {
  name: "yun",
  hobby: "coding",
};

let sample2 = sample; // 얕은복사
sample2.name = "jyun";

let sample3 = { ...sample }; // 깊은복사
sample3.name = "yundev";

console.log(sample); // {name: 'jyun', hobby: 'coding'}
console.log(sample2); // {name: 'jyun', hobby: 'coding'}
console.log(sample3); //{name: 'yundev', hobby: 'coding'}
  • 얕은복사 : 객체의 참조값을 복사함 -> 원본객체가 수정될 수 있어 위험함
  • 깊은복사 : 새로운 객체를 생성하면서 프로피터만 따로 복사함 -> 원본객체가 수정될 일이 없어 안전함

  • 객체 비교 객체간의 비교는 기본적으로 참조값을 기준으로 이루어진다.
console.log(sample === sample2); // true
console.log(sample === sample3); // false
console.log(JSON.stringify(sample) === JSON.stringify(sample3)); //true

객체를 분자열로 변환하는 JSON.stringify() 함수를 이용하면 깊은 비교 가능

반복문을 이용한 배열이나 객체 순회

  • 배열 순회
  1. 인덱스를 이용한 반복
for (let item of arr) {
  console.log(item);
}
  1. for of 반목
for (let item of arr) {
  console.log(item);
}
  • 객체 순회
  1. Object.keys()
let keys = Object.keys(person);

for (let i = 0; i < keys.length; i++) {
  console.log(person[keys[i]]);
}

for (let key of keys) {
  console.log(person[key]);
}
  1. Object.values()
let values = Object.values(person);

for (let value of values) {
  console.log(value);
}
  1. for in
for (let key in person) {
  const value = person[key];
  console.log(value);
}

for (let a in arr) {
  console.log(a);
}

배열 메서드

요소 조작

  • push : 배열의 맨 뒤에 새로운 요소 추가
  • pop : 배열의 맨 뒤에 있는 요소 제거하고 반환
  • shift : 배열의 맨 앞에 있는 요소를 제거 반환
  • unshift : 배열의 맨 앞에 새로운 요소를 추가
  • slice : 배열의 범위를 잘라내서 새로운 배열을 반환
  • concat : 배열을 이어 붙여서 새로운 배열을 반환

순회와 탐색

  • forEach
arr.forEach(function (item, idx, arr) {
  console.log(idx, item * 2);
});

arr.forEach((item) => {
  console.log(item * 2);
});
  • include 배열에 특정 요소가 있는 지 확인하는 메서드
let isInclude = arr.includes(3);
console.log(isInclude); // true
  • indexOf 특정 요소의 인덱스를 찾아서 반환하는 메서드 (얕은 비교)
let idx = arr.indexOf(3);
console.log(idx); // 2
  • findIndex 모든 요소를 순회하면서, 콜백 함수를 만족하는 요소의 인덱스를 반환하는 메서드
const findIdx = arr.findIndex((item) => {
  if (item === 2) return true;
});

console.log(findIdx); // 2
  • find 모든 요소를 순회하면서, 콜백 함수를 만족하는 요소를 반환
const findItem = arr.find((item) => {
  if (item === 2) return true;
});

console.log(findItem); // 2

배열 변형

  • filter 기존 배열에서 조건을 만족하는 요수들만 필터링하여 새로운 배열로 반환
let filterItem = arr3.filter((item) => item.age === 22);
console.log(filterItem);
  • map 모든 요소를 순회하면서, 콜백 함수를 실행하고 그 결과를 모아서 새로운 배열로 반환
const mapResult = arr2.map((item, idx, arr) => {
  return item * 2;
});

console.log(mapResult); // [8, 2, 4, 6, 10, 12]
  • sort 배열을 사전 순으로 정렬
arr.sort();

// 오름차순
arr.sort((a, b) => {
  if (a > b) {
    return 1; //b가 a 앞
  } else if (a < b) {
    return -1; //a가 b 앞
  } else {
    return 0; // 순서그대로
  }
});
  • toSorted() 정렬된 새로운 배열을 반환

  • join(구분자) 배열의 모든 요소를 하나의 문자열로 합쳐서 반환

Date

  • Date 객체
let date1 = new Date();
console.log(date1); // Tue Sep 10 2024 09:34:38 GMT+0900 (한국 표준시)

let date2 = new Date("2000-01-01");
console.log(date2); // Sat Jan 01 2000 09:00:00 GMT+0900 (한국 표준시)

let date3 = new Date("2000-01-01/10:10:10");
console.log(date3); // Sat Jan 01 2000 10:10:10 GMT+0900 (한국 표준시)

let date4 = new Date(2000, 0, 1, 10, 10, 10);
console.log(date4); // Sat Jan 01 2000 10:10:10 GMT+0900 (한국 표준시)
  • 타임스템프 특정 시간이 “1970.01.01 00시 00분 00초”로 부터 몇 ms가 지났는지 의미하는 숫자 값
let ts1 = date1.getTime();
let date5 = new Date(ts1);
console.log(date5); // Tue Sep 10 2024 09:37:58 GMT+0900 (한국 표준시)
  • 시간 요소

    • year : getFullYear();
    • month : getMonth(); (월은 0부터 시작)
    • date : getDate();
    • hour : getHours();
    • minute : getMinutes();
    • seconds = getSeconds();
  • 포맷

console.log(date1.toDateString()); // Tue Sep 10 2024
console.log(date1.toLocaleString()); // 2024. 9.  10. 오전 9:42:26
console.log(date1.toLocaleDateString()); // 2024. 9. 10.
console.log(date1.toLocaleTimeString()); // 오전 9:42:26
console.log(date1.toISOString()); // 2024-09-10T00:42:26.313Z

동기와 비동기

동기 : 여러개의 작업을 순서대로 하나씩 처리

자바스크립트는 일반적으로 동기적으로 작업이 실행된다.

비동기 : 여러개의 작업을 순서대로 처리하지 않음, 여러개의 작업을 동시에 실행 가능

자바스크립트의 비동기 작업들은 자바스크립트 엔진이 아닌 Web APIs 에서 실행됨

console.log(1);

setTimeout(() => {
  console.log(2);
}, 3000); //web api 에서 실행

console.log(3);
Alt text

콜백함수

// 음식을 주문하는 상황
function orderFood(callback) {
  setTimeout(() => {
    const food = "요아정";
    callback(food);
  }, 2000);
}

orderFood((food) => {
  console.log(`${food} 배달왔습니다.`);
});

Promise

비동기 작업을 효율적으로 처리할 수 있게 도와주는 자바스크립트 내장 객체 (콜백 지옥의 해결 방법)

3가지 상태

  • 대기 (Pending) : 아직 작업이 완료되지 않은 상태
  • 성공 (Fulfilled) : 비동기 작업이 성공적으로 마무리 된 상태
  • 실패 (Rejected) : 비동기 작업이 실패한 상태
const promise = new Promise((resolve, reject) => {
  // 비동기 작업을 실행하는 함수
  //executor
  setTimeout(() => {
    console.log("안녕");
    resolve("resolve"); // 성공상태로 바꿈
    // reject("reject")
  }, 2000);
});

console.log(promise); // pending 상태

setTimeout(() => {
  console.log(promise); // fulfield 상태
}, 3000);
  • then 과 catch
promise.then((value) => {
  console.log(`then은 ${value} 상태에만 실행`); //then은 resolve 상태에만 실행
});

promise.catch((error) => {
  console.log(`catch는 ${error} 상태에만 실행`); //catch는 reject 상태에만 실행
});

promise chaining

promise
  .then((value) => {
    console.log(`then은 ${value} 상태에만 실행`);
  })
  .catch((error) => {
    console.log(`catch는 ${error} 상태에만 실행`);
  });

콜백지옥 해결

function add10(num) {
  const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      if (typeof num === "number") {
        resolve(num + 10);
      } else {
        reject("num은 숫자 형식이 아닙니다.");
      }
    }, 2000);
  });

  return promise;
}

add10(0)
  .then((result) => {
    console.log(result);
    return add10(result);
  })
  .then((result) => {
    console.log(result);
    return add10(result);
  });

async/await

async : 어떤 함수를 비동기 함수로 만들어주는 키워드, 함수가 프로마스를 반환하도록 변환해준다,

await : async 함수 내부에서만 사용이 가능 한 키워드, 비동기 함수가 다 처리되기를 기다리는 역할

비동기 함수를 동기함수 처럼 처리하게 해줌

async function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        name: "yun",
        hobby: "coding",
      });
    }, 2000);
  });
}

async function printData() {
  const data = await getData(); //getData() 가 끝나길 기다려줌
  console.log(data);
}

printData();

댓글남기기