자바스크립트 기초 - ajax, 배열, 고차함수, 비동기 프로그래밍

Minhyeok Kim·2022년 7월 26일
0
post-thumbnail

[14장 배열 이어서...]

배열 메서드 복습!

자바스크립트에서 배열은 객체이다.
일반객체와 배열은 다른점을 갖는데, 가장 명확한 차이는 값의 순서와 Length 프로퍼티이다.

배열 고차함수
함수를 인수로 전달받거나 함수를 반환하느느 함수를 말한다.
함수형 프로그래밍은 조건문과 반복문을 제거(복잡성 해결)하고 변수의 사용을 억제(상테변경을 피함)하는 프로그래밍 패러다임이다.
순수함수를 통해 부수효과를 최대한 억제하고자 한다.
고차함수를 만들수도 있지만 자바스크립트에서 제공하고 있는 고차함수를 잘 활용하면 좋다.

Array.prototype.sort
배열의 요소를 정렬한다. 기본적으로 오름차순
if, 내림차순으로 정렬하고 싶으면, reverse를 이용해
ㄱ ㄴ ㄷ .. a b c ...
숫자를 정렬할 때는 주의가 필요하다. why? 숫자를 문자처럼 보고 정렬하기 때문이다.
(유니코드 코드 포인트의 순서를 따르기 때문)

// 숫자를 정렬할 때
const points = [40, 100, 1, 5, 2, 25, 10];

// 숫자 배열의 오름차순 정렬. 비교 함수의 반환값이
// 0 보다 작으면 a를 우선하여 정렬한다.
points.sort((a, b) => a - b);
console.log(points); // [1, 2, 5, 10, 25, 40, 100]

//숫자 배열의 내림차순 정렬. 비교함수의 반환값이
// 0보다 작으면 b를 우선하여 정렬한다.
points.sort((a, b) => b - a);
console.log(points); // [100, 40, 25, 10, 5, 2, 1]

Array.prototype.forEach
자신의 내부에서 반복문을 실행한다.

// pows
const numbers = [1, 2, 3];
let pows = [];
// numbers 라는 배열과 pows 라는 배열이 생성

for (let i = 0; i < numbers.length; i++) {
  // numbers 의 요소 개수만큼 for 문을 반복하겠다 : 3번 이겠지?
  // i = 0 에서 한번 돌았고, i 에 1이 더해졌어
  // 다음, i = 1 이고 -조건충족- 여기서 한번 돌아서, i 에 1이 더해져 2가되었어
  // 반복
  // i 가 3이되면 실행이 되지 않고 종료
  pows.push(numbers[i] ** 2);
  // 1번째, i 가 1 이니까 1의 제곱은 1
  // 2번째, i 가 2 니까 2의 제곱은 4
  // 3번째, i 가 3 이니까 3의 제곱은 9
}
console.log(pows);

// forEach 는 모든 요소에 접근할 때 사용한다
// break 나 continue 를 사용할 수 없다.
const numbers = [2, 5, 7];
let pows = [];

numbers.forEach((item) => pows.push(item ** 2));
//  for (let i = 0; i < numbers.length; i++){
//    pows.push(numbers[i] ** 2);
// }
console.log(pows); // (3) [4, 25, 79]

Array.prototype.map
자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출한다.
콜백함수의 반환값들로 구성된 새로운 배열을 반환한다.

const numbers = [1, 4, 9];
const roots = numbers.map((item) => item * 9);

console.log(roots); // (3) [9, 36, 81]
console.log(numbers); // (3) [1, 4, 9]

const sqrtc = numbers.map((item) => Math.sqrt(item));

console.log(sqrtc); // (3) [1, 2, 3]
console.log(numbers); // (3) [1, 4, 9]

Array.prototype.filter
콜백함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다.

const numbers = [1, 2, 3, 4, 5, 2];
const odds = numbers.filter((item) => item % 2 === 0);
// 2로 나눈 나머지가 0이면 true == 1
// true 로 나오는 요소들을 모아서 새로운 배열을 생성한다.
// 중복된요소들 포함
console.log(odds); // (3) [2, 4, 2]
console.log(numbers); // (6) [1, 2, 3, 4, 5, 2]

Array.prototype.reduce
자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달 받은 콜백함수를 반복 호출
콜백함수의 반환값을 다음 순회시에 콜백함수 첫번째 인수로 전달하면서 콜백함수를 호출하여 하나의 결과 값을 만들어 반환한다.

const values = [1, 2, 3, 4, 5, 6];
// 변수 average 값 을 출력하는 내용에서 reduce를 작성하는데
// acc : 값을 저장하는 장치, 여기서 초기값 : 0, 이후에 반환되는 값이
// acc에 재저장 된다.
// cur : 현재 값, 요소 초기값은 : 1
// i : 인덱스, 인덱스 초기값 : 0
// length : 요소의 개수
const average = values.reduce((acc, cur, i, { length }) => {
  return i === length - 1 ? (acc + cur) / length : acc + cur;
  // true 면 (acc + cur) / length 실행
  // false 면 acc + cur 실행
}, 0);

console.log(average); // 3.5

// reduce 예제 2
const fruits = ["바나나", "사과", "오렌지", "오렌지", "사과"];

const count = fruits.reduce((acc, cur) => {
  // 천번째 순회시 acc는 초기값인 {} 이고 cur 은 처번째 요소인 "바나나"
  // 초기가밧으로 전달받은 빈 객체에 요소값인 cur을 프로퍼티 키로,
  // 요소의 개수를 프로퍼티 값으로 할당한다.
  // 만약 프로퍼티 값이 undefined(처음 등장하는 요소)이면
  // 프로퍼티 값을 1로 초기화한다.
  acc[cur] = (acc[cur] || 0) + 1;
  return acc;
}, {});

// if 함수로 표현하면
const count = fruits.reduce((acc, cur) => {
  if (acc[cur]) {
    acc[cur]++;
  } else {
    acc[cur] = 1;
  }
  return acc;
}, {});

// 콜백함수는 총 5번 호출되고 다음과 같은 결과값을 반환한다.
/*
{바나나:1} => {바나나:1, 사과:1} => {바나나:1, 사과:1, 오렌지:1}
=> {바나나:1, 사과:1, 오렌지:2} => {바나나:1, 사과:2, 오렌지:2}
*/
console.log(count); // {바나나:1, 사과:2, 오렌지:2}

Array.prototype.find
자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백함수를 호출하여 반환값이 true 인 첫번째 요소를 반환한다(찾기 기능)

// find 메서드를 이용하여 원하는 값을 찾아보자
const users = [
  { id: 1, name: "Lee" },
  { id: 2, name: "Kim" },
  { id: 2, name: "Choi" },
  { id: 3, name: "Park" },
];

users.find((user) => user.id === 2);
console.log(users.find((user) => user.id === 2));

스프레드 문법
스프레드 문법(전개 문법) ... 은 하나로 뭉쳐있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록으로 만든다.

const laa = [1, 2, 3];
console.log(laa); // (3) [1, 2, 3]

console.log(...[1, 2, 3]); // 1 2 3 :값들의 목록?
console.log(..."Hello"); // H e l l o
console.log(...{ a: 1, b: 2 }); // error
// 객체는 스프레드 문법을 사용할 수 없다.
const list = ...[1,2,3]; // error :변수에도 선언할 수 없다.

// 함수 호출문의 인수 목록에서 사용하는 경우들
// Math.max 메서드 : 최대값을 반환하는 경우
const arr = [1, 2, 3];
// 스프레드 문법을 사용하여 배열 arr을 1, 2, 3으로 펼쳐서
// Math.max에 전달한다.
// Math.max(...[1, 2, 3])은 Math.max(1, 2, 3)과 같다.
const max = Math.max(...arr);
console.log(max); // 3

// Rest 파라미터는 인수들의 목록을 배열로 전달받는다.
function foo(...rest) {
  console.log(rest); // 1, 2, 3 -> (3) [1, 2, 3]
}

// 스프레드 문법은 배열과 같은 이터러블을 펼쳐서
// 개별적인 값들의 목록을 만든다.
// [1, 2, 3] -> 1, 2, 3
foo(...[1, 2, 3]);

// rest 에제2
const arr = [3, 4, 7, 8, 9, 1, 2];
function foo(a, b, c, ...rest) {
  console.log(a); // 3
  console.log(c); // 7
  console.log(rest); // (4) [8, 9, 1, 2]
}
foo(...arr);

// 스프레드 프로퍼티
// 객체 복사(얕은 복사)
const obj = {
  x: 1,
  y: 2,
  aaa() {
    console.log(this.x);
  },
};
const copy = { ...obj };
// obj 객체의 값들을 모두 복사한다
console.log(copy); // {x:1, y:2, aaa:f} :
console.log(obj === copy); // false : obj 랑 copy랑 일치하는지
// 결과값을 불리언타입으로 반환

// 객체 병합
const arr = {
  r: 4,
  e: 6,
};

const merged = { x: 1, ...{ a: 5, b: 6 }, ...arr };
console.log(merged);
// {x:1, a: 5, b: 6, r: 5, e: 6}

[15장 이터러블]

.
.
. Skip for now

[16징 비동기 프로그래밍]

동기처리와 비동기처리
자바스크립트 엔진은 단 하나의 실행컨텍스트 스택을 갖는다. (싱글 쓰레드)
동기 : 순서를 기다렸다가 하나하나 진행
비동기 : 앞에 순서와 상관없이 본인 할거 하면서 진행
but, 이벤트루프를 통해 마치 멀티 쓰레드인 것 처럼 보이게 한다.

이벤트 루프와 태스크 큐
콜스택 : 실행 컨텍스트가 추가 되고 제거되는 스택자료구조인 실행 컨텍스트 스택
: 객체가 저장되는 메모리 공간
태스크 큐 : 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역
(자바스크립트 엔진이 싱글이기 때문에 넘어가는곳)
이벤트 루프 : 콜 스택에 실행중인 실행 컨텍스트가 있는지, 태스크 큐에 대기중인 함수가 있는지 확인한다. 콜 스택이 비어있고, 태스크큐에 대기중인 함수가 있다면, 이벤트 루프는 순차적으로 태스크 큐에 대기중인 함수를 콜스택으로 이동시킨다. 이때 콜 스택으로 이동한 함수는 실행된다.

Web API : 웹 브라우저에서 제공하는 API로 AJAX난 Timeout등의 비동기 작업을 실행
(AJAX : XMLHttpRequest)

setTimeout 함수와 유사하게 일정 시간이 경과한 이후에 콜백 함수를 호출하는 sleep함수

// 동기 처리방식
// sleep 함수는 일정 시간(delay)이 경과한 이후에 콜백함수(func)를 호출한다.
function sleep(func, delay) {
  // Date.now()는 현재 시간을 숫자(ms)로 반환한다.
  const delayUntil = Date.now() + delay;
  // 현재 시간(Date.now())에 delay를 더한 delayUntil이
  // 현재 시간보다 작으면 계속 반복한다.
  while (Date.now() < delayUntil);
  func();
}
function foo() {
  console.log("foo");
}

function bar() {
  console.log("bar");
}
// sleep 함수는 3초 이상 실행된다.
sleep(foo, 3 * 1000);
// Bar 함수는 sleep 함수의 실행이 종료된 이후에 호출되므로
// 3초 이상 블로킹된다.
bar();
// (3초경과 후) foo 호출 -> bar 호출
// 동기 처리방식은 순서가 보장되다는 장점은 있지만 태스크가 종료될 때까지
// 이후 태스크들이 블로킹되는 단점이 있다.

//setTimeout 함수
function foo() {
  console.log("foo");
}
function bar() {
  console.log("bar");
}
function koo() {
  console.log("koo");
}
// 타이머 함수 setTimeout은 일정 시간이 경과한 이후에
// 콜백함수 foo를 호출한다.
// 타이머 함수 setTimeout은 bar 함수를 블로킹 하지 않는다.

setTimeout(foo, 3 * 1000);
setTimeout(koo, 2 * 1000);
bar();
// bar 호출 -> (2초경과후) bar 호출 -> (1초경과후) foo 호출

// setTimeout 함수의 최소 딜레이 시간 4ms
function foo() {
  console.log("foo");
}
function bar() {
  console.log("bar");
}
setTimeout(foo, 0);
bar();
// bar
// foo
// 지연시간이 0 이지만 지연시간 4ms 이하인 경우 최소 지연시간 4ms로 지정된다.
// 따라서 4ms 후에 콜백함수 foo가 태스크 큐에 푸시되어 대기하게 된다.

Ajax(Asynchronouse JavaScript and XML)
자바스크립트를 사용하여 브러우저가 서버에게 비동기 방식으로 데이터를 요청하고,
서버가 응답한 데이터를 수신하여 웹페이지를 동적으로 갱신하는 프로그래밍 방식

"웹 브라우저에서 자바스크립트와 Ajax를 기반으로 동작하는 구글맵스가 데스크톱 애플리케이션과 비교해 손색이 없을 정도의 퍼포먼스와 부드러운 화면전환 효과를 보여준적이 있다"

전통적인 웹페이지의 생명주기
-변경할 필요가 없는 부분까지 포함된 완전한 HTML을 서버로부터 매번 다시 전송받는다
-처음부터 다시 랜더링 한다.
-클라이언트와 서버와의 통신이 동기 방식으로 동작하기 때문에 서버로부터 응답이 있을 때까지 다음 처리는 블로킹된다.

Ajax의 방식
-필요한 데이터만 서버로부터 전송받아
-필요한 부분만 랜더링한다
-비동기방식으로 동작하기 때문에 블로킹이 발생하지 않는다.

JSON (JavaScript Object Notion)
클라이언트와 서버간의 HTTP통신을 위한 텍스트 데이터 포맷

0개의 댓글