[유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 - 1주차 학습 내용 정리(Javascript)

🥔감자로그🍟·2024년 7월 21일
0
post-thumbnail

7월 15일(월)부터 7월 19일(금)까지 Next.js 프로젝트 캠프에서 배운 내용을 정리해보았다.

JAVASCRIPT

Javascript 실행 방법

Javascript를 실행하는 방법에는 여러가지가 있다.
1. 코드 러너 등의 익스텐션 사용
2. node 명령어를 사용
3. 외부 스크립트 방식
4. 내부 스크립트 방식
5. 웹 브라우저 개발자 도구 Console 탭에 작성

외부 스크립트 방식(async와 defer)

외부 스크립트 방식은 <script src="..."></script> 처럼 html 파일 내에서 <script> 태그를 사용하는 방식인데, 파싱을 고려하여 다양한 방식으로 사용할 수 있다.

head 태그 사이에 작성하는 방법, body 태그가 끝나기 전에 사용하는 방법 등 위치를 변경하는 방법이 있고, 또 asyncdefer 속성을 활용할 수도 있다.

asyncdefer는 스크립트를 다운로드 하는 동안 HTML이 중단되지 ㅏㅇㄶ고, async는 스크립트를 다운로드 했을 때 곧바로 실행하고 defer은 문서를 완전히 다 읽은 후 실행한다는 차이가 있다.

내부 스크립트 방식

내부 스크립트 방식은 외부스크립트 방식처럼 <script> 태그를 사용하기는 하지만, js 파일을 호출하는 것이 아닌 <script>...</script> 형태로 js 코드를 <script> 태그 사이에 작성하여 사용한다.

변수와 상수

자바스크립트 변수 키워드는 var, let, const이 있다.

var을 사용하는 것은 범죄입니다. 절대 사용하지 않도록 합니다

let은 재할당이 필요할 때, const는 재할당이 필요 없을 때 사용한다.

자료형

기본 자료형

숫자, 문자열, 논리형, 특수자료형(undefined), 심볼, null

Symbol()
절대로 중복되지 않는 유니크한 값을 생성하는 자료형이다(자주 사용하지는 않는다).

const a = symbol();
const b = symbol();

이렇게 선언하여도 두 값은 같은 값이 아니다.
괄호안에 설명 등 문자열을 작성할 수도 있다.

참조 자료형

배열, 객체, 함수

참조 자료형은 값이 아닌 그 값을 가진 메모리 주소를 참조한다.

🐞

typeof를 사용하면 해당 값의 자료형을 알 수 있다. 그런데 배열의 자료형을 출력해보면..? array가 아니라 object가 출력된다. 도대체 왜???🧐🧐🧐

재미있는 버그 중 하나로, 무려 개발자가 공식적으로 인정한 실수이다. 바꾸기엔 이미 이를 고려하여 수많은 코드가 작성되었고..수정하는 순간 오류지옥의 시작일것이기에 수정하지 않았고 Javascript 상에서 배열은 여전히 object로 출력된다.🤭배열이랑 객체 중 누가 더 억울하지

연산자

산술연산자, 증강연산자, 대입연산자, 복합대입연산자, 비교연산자, 삼항연산자, 논리 연산자

비교연산자
=====이 있는데, ==은 동등, ===은 일치이다. 타입의 일치 여부까지 판단하는 것은 ===이다.

삼항연산자
참이면 두번째 피연산자를, 거짓이면 세번째 피연산자를 실행한다.

  • 0, undefined, null, NaN, "" 등은 거짓으로 판별한다.
  • 함수, 문자열, 배열, 0보다 큰 수는 참으로 판별한다.
  • 다만 이는 삼항연산자에 해당하는 것으로, 논리연산자에서 이를 활용하고자 할 땐 부정연산을 사용할 수 있다.

조건문

switch-case, if-else

if-else를 사용할 때는 if-else if-else 순으로 사용한다. if-if-if는 왜 안쓰는걸까?🧐

if-if-if도 사용할 수는 있다. 하지만 if, else if을 사용하는 것에 비해 퍼포먼스가 떨어진다. if를 연속해서 사용하면, 앞선 조건이 참일 때, 뒤 조건으로 평가가 이어진다. 따라서 모든 조건을 만족한다면, 분별 없이 모든 경우를 다 수행하게 된다.

반복문

while, do-while, for

항상 보는 그 for문. 자바스크립트에서는 이렇게 쓴다.

const arr = ["banana", "apple", "orange"];
for(let index in arr){
  console.log(arr[index]);
}

const obj = {name: "철수", age: 20};
for(let key in obj){
  console.log(obj[key]);
}

배열에서만 사용 가능한 for-of도 있다

for(let value of arr){
  console.log(value);
}

함수

함수 선언식, 함수 표현식, 화살표 함수

  • 함수 선언식은 늘 사용하는 그 방식
function add() {}
add();
  • 함수 표현식은 변수에 함수를 담는 방식이다
const add = function add() {};
const add = function () {};
add();
  • 화살표 함수는 화살표 함수
const add = () => {};
add();

this

자기 자신을 호출한 객체를 가리키는 특수한 키워드

const memebership() = {name: "킁킁잉", joied : function() {console.log(this);}, }; 

membership.joined();

이와 같은 방식으로 자기 자신을 호출한 객체를 가리킬 수 있다.

  • 전역적인 부분에서 호출되는 thiswindow이다.
  • this를 사용할거면 화살표 함수는 사용하지 않는 것이 좋다. 사용이 가능하긴 한데,,this를 로직으로 사용할거면 일반 함수를 사용해야 의도한 동작대로 사용이 가능하다.

bind()

bind() 메서드를 사용하여, this의 값을 원하는대로 고정할 수 있다.

const membership() = {name: "킁킁잉", joined: function(){return ${this.name}님이 가입햇습니다;}.bind({name:"황다경"}),};

실행 컨텍스트

자바스크립트 코드가 실행될 때 필요한 환경을 제공해주는 갳게

스택

FILO 자료구조

자바스크립트는 스택 구조를 도입하여 코드를 실행시킨다. 스키립트를 실행시키는 스택을 콜스택이라고 한다.

코드를 실행하면 실행 컨텍스트 영역을 하나 생성하고, 가장 아래에 딸린 실행 컨텍스트를 전역 실행 컨텍스트라고 부른다. 모든 코드는 전역 실행 컨텍스트 안에서 실행된다. 실행 컨텍스트의 실행이 끝나면, 콜스택에서 제거된다. 함수가 실행이 될 때 새로운 실행 컨텍스트가 생성된다.

레코드

생성 단계에서 코드를 기록한다.

내부적으로 생성과 실행이라는 두 개의 스택으로 코드가 동작이 된다. 레코드 객체는 생성 단계에서 코드를 훑어서 변수선언, 함수선언 등을 파악하여 기록한다.
이 때 var일 경우 undefined로 값을 초기화까지 시켜주지만, let,const는 초기화해주지 않는다. 레퍼런스 에러를 조심하자

실행은 생성 단계에서 생성한 것을 참조하여 코드를 실행, 업데이트한다. 업데이트는 미완성된 기록을 업데이트 하는 것으로, 업데이트 전까지는 참조할 수 없다. 물론, 완성된 기록은 참조 가능하다(var, function은 완성, let, const는 미완성이다).

아우터

아래의 실행 컨텍스트와 연결하는 연결 통로

실행 컨텍스트가 달라지면 변수명의 중복 선언이 가능하다(같은 컨텍스트 내에서는 불가능).
컨텍스트에서 변수를 찾는 순위는 1. 같은 실행 컨텍스트 내에서 2. 하위 실행 컨텍스트 내에서이다. 이 역할이 가능하게 하는 것이 아우터이다.

전역 컨텍스트에서 아우터 객체는 아무 의미가 없다. 하위 컨텍스트가 없으니까 당연한 것. 하지만 위에 쌓이는 컨텍스트들은 아래의 컨텍스트로 연결할 수 있는 방법이 필요하고, 아우터가 이 역할을 해준다.
이는 단방향 연결로, 위에서 아래로 연결된다. 따라서 함수 컨텍스트에 변수 선언 후 전역 컨텍스트에서 해당 변수를 쓰려고 하면 참조할 수 없다.

호이스팅

선언부가 최상단으로 올라가는 현상

자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모두 모아서 유효 범위 최상단에 선언한다.

var변수 선언과 함수 선언문에서만 호이스팅이 일어난다.

클로저

실행 컨텍스트가 정상적으로 제거(종료)되지 못하는 현상

function outerFunc() {
  let count = 0;
  return function innerFunc() {
    count++;
    console.log(count);
  }
}
const counter = outerFunc();

카운터 변수에는 innerFunc 함수가 담긴다. 실행시키면

counter(); //1
counter(); //2
counter(); //3

이렇게 실행할 때마다 값이 1씩 증가한다. 왜 0이나 1이 아닐까?

컨텍스트가 끝나고 메모리에서 제거하려고 할 때, count를 참조하고 있기 때문에 전역 실행 컨텍스트를 제거하지 못한다. 임시 보관되고, 호출하면 호출할수록 찌꺼기들이 쌓은디.
이는 메모리 누수(낭비)를 발생시키고, 퍼포먼스가 떨어진다. 따라서 의도적으로 클로저 코드를 사용했다면 코드 종료 이전 counter = null;등으로 끊어줘야 한다.

생성자 함수

객체의 속성이 같고, 값이 다른 경우에 객체를 생성할 수 있는 생성자 함수를 제공한다.

function User() { //생성자 함수명은 대문자로 시작하기
  this.name = "John";
  this.age = 30;
  this.gender = "male";
}

new 키워드를 사용하여

const user1 = new User();

이렇게 속성은 같은데 서로 다른 값을 가진 객체들을 생성할 수 있다.
붕어빵 틀! 🐟🍞

프로토타입

함수를 생성하고 콘솔에서 확인해보면

prototype이 있다.

함수만 가지는 프로토타입 속성으로, 모든 함수는 자신과 1:1로 매칭되는 프로토타입 객체 공간을 가진다.

컨스트럭터

컨스트럭터는 자신이 관련되어 있는 함수를 가진다.
함수에서는 프로토타입을, 프로토타입에서는 컨스트럭터를 활용하여 대응하는 함수에 접근 하는 것. 함수-프로토타입은 상호 참조가 가능하다!

프로토타입 체인

인스턴스 내부의 __proto__ 속성으로 자신을 생성한 생성자 함수의 프로토타입 객체를 참조하는 현상

연결된 프로토타입 객체를 타고 올라가서 원하는 객체를 찾아내는 현상을 프로토타입 체이닝이라고 한다.

클래스

자바스크립트는 원래 클래스가 없다. 클래스 사용을 위해 생성자 함수를 사용했었는데, ES6에서 클래스가 도입되었다.

클래스 내부 동작은 생성자 프로토타입 기반이지만, 슈가 신택스를 추가한 것ㄱ

ES6 이전의 상속

function Shape(color){
    this.color = color;
    this.getColor = function(){
        return `이 도형의 색상은 ${this.color}입니다`;
    };
}

const shape1 = new Shape("red");
console.log(shape1.color);
console.log(shape1.getColor());

function Rectangle(color, width, height){
    this.color = color;
    this.width = width;
    this.height = height;
    this.getArea = function(){
        return this.width = this.height;
    };
}

const rect1 = new Rectangle("blue", 20, 20);
const.log(rect1.getArea());

function Rectangle(color, width, height){
    Shape.call(this, color);
    this.width = width;
    this.height = height;
    this.getArea = function(){
        return this.width = this.height;
    };
}
const rect1 = new Rectangle("blue", 20, 20);
const.log(rect1.getColor()); //정상 호출

.call을 사용하여 상위의 속성을 상속받았다.

클래스 문법

class Shape {
  constructor(color) {
    this.color = color;
  }
  getColor() {
    return `이 도형의 색상은 ${this.color} 입니다.`;
  }
}

const shape1 = new Shape("red");
console.log(shape1);

클래스로 생성한 인스턴스는 자동으로 프로토타입 객체 쪽으로 등록이 된다.

extends를 사용하여 클래스의 상속을 사용한다.

class Rectangle extends Shape {
  constructor(color, width, height) {
    super(color); //상위 클래스의 color
    this.width = width;
    this.height = height;
  }
  getArea() {
    return (this.width = this.height);
  }
}

const rect1 = new Rectangle("blue", 20, 20);
console.dir(rect1);
console.log(rect1.getColor());
console.log(rect1.getArea());

setter

class Car {
  constructor(speed) {
    this.speed = speed;
  }

  set speed(speed) {
    if (speed < 0) {
      throw new Error("속도는 음수가 될 수 없습니다");
    }
  }

  getSpeed() {
    return `현재 속도는 ${this.speed}입니다.`;
  }
}

const car1 = new Car(100);
console.log(car1.getspeed());

set을 사용하여 제어하고 있기 때문에 speed가 음수 값이 되면 에러메시지가 출력된다. 음수일 경우 에러가 발생하지만 양수일 경우에도, 아무 동작을 하지 않는다. set을 사용하면 앞으로의 제어는 모두 set이 관여하게 되고, 따라서 동작을 할 경우에 대한 제어도 set내에 설정해주어야 한다.

getter

get 키워드를 사용한다. 속성을 읽으려고 할 때, 함수를 호출하여 값을 리턴한다.

#

#을 사용하면 private한 변수 선언이 가능하다. 외부 요인에 의해 바뀌지 않고, 최초 선언한 값을 그대로 간직한다.

표준 내장 객체

자바스크립트 엔진에 기본적으로 내장되어 있는 객체

자주 쓰이는 표준 내장 객체

  • Object
  • Function
  • Array
  • String
  • Boolean
  • Number
  • Math
  • Date
  • RegExp

array.lengthstring.length는 다르다. 같은 동작을 공유하는 것이 아니고, 각자의 객체 내에 length가 각각 포함되어 있다.

string이 객체라고?

const str = "Hello";
console.dir(str);
console.log(str);

를 콘솔에 찍어보면 Hello가 나온다. 프로토타입이나 다른 속성은 눈을 씻고 찾아봐도 없는데 이게 어떻게 객체일까.

const str = new String("Hello");

이렇게 생성하면 객체로 보인다 또.

자료형과 관련되어 있는 생성자 객체로 만들어야 하지만, 자바스크립트가 문법적으로 단축하여 표현할 수 있는 표기법을 제공하는 것으로, 리터럴 표기법 이라고 한다.

비동기

동기

코드가 순차적으로 실행되는 것

코드의 순서가 보장이 된다. 무조건 작성된 순서대로!

비동기

코드가 순차적으로 실행되지 않는 것

코드의 순서가 보장되지 않는다.
자바스크립트는 싱글 스레드 언어로, 하나에 한 번의 처리만 가능하다. 그렇기 때문에 동기적으로 실행되는 언어이다. 동기적 실행 언어의 단점은 한 번에 하나의 작업만 처리 할 수 있기 때문에 모든 자바스크립트 내부의 코드가 동기적으로 처리가 된다면 일부 부하가 걸리는 작업을 모두 기다려 주어야 한다. 매우 비효율적이다.

싱글 스레드 언어는 비동기적으로 실행되는 코드가 필요하다.

콜백 함수

다른 함수의 매개 변수로 전달되어 그 함수가 실행되는 동안 특정 시점에 호출되는 함수

function task1(callback) {
  setTimeout(() => {
    console.log("task1 시작");
    callback();
  }, 1000);
}

function task2() {
  console.log("task2 시작");
}

task1(task2);

비동기 콜백 함수이다. 비동기 작업이 끝난 다음 호출되는 형태이다.
위 코드는 task2까지만 작성하여 그 형태를 파악하기 편하지만, 함수가 중첩되면 중첩될수록 코드의 depth가 깊어진다.

콜백 지옥의 시작이다.

Promise

자바스크립트 비동기 작업을 처리하기 위한 객체

3가지 상태가 있다.

  • pending: 비동기 처리가 아직 수행되지 않는 상태
  • fulfilled: 비동기 처리가 수행된 상태
  • rejected: 비동기 처리가 실패한 상태
    then, catch, finally로 결과값을 받는다.
const promise = new Promise((resolve, reject)) =>{
    //비동기 작업을 수행하는 코드
    //작업이 성공하면 resolve(value) 호출
    //작업이 실패하면 reject(error) 호출
    console.log("doing something...");
    resolve("sucess"); //fulfulled가 되면서 값이 들어감-뭐라도 일단 넘겨줘야됨
    reject(); //안넘겨줘도 상광없음. 다만 사유를 넘기지 않는다면 에러 발생 원인을 모르겠지
});

promise
.then((value) => console.log(value)) //fulfilled 상탱서 호출
.catch((error) => console.error(error)) //reject 상태서 호출
.finally(() => console.log("finally")); //resolve, reject 상관없이 무조건 실행

async, await

  • function 앞에 async를 붙이면 해당 함수는 항상 프라미스를 반환한다.
  • await 키워드를 사용하여 프라미스가 처리될 때까지 함수 실행을 기다리게 만든다.

DOM

HTML(태그)을 객체로 표현한 것

문서 객체를 제어하기 위한 모델을 의미한다.

document.querySelector()

두가지만 기억하면 된다. document.querySelector과,document.querySelectorAll이다.

get 메서드가 있긴 한데, 현대의 인터넷에서 get~을 사용한 퍼포먼스적 혜택은 별로 없기 때문에 document.querySelector을 사용하자.

이벤트

사용자가 웹 페이지의 특정 요소와 상호 작용할 때 발생하는 것

  • 이벤트 타겟 -> 이벤트가 발생한 요소
  • 이벤트 타입 -> click, keydown, keyup, mouseover..
  • 이벤트 핸들러 -> 이벤트가 발생했을 때 실행할 코드
  • 이벤트 등록 -> 이벤트 타겟에, 이벤트 타입과 이벤트 핸들러 동작을 등록하는 것
const inputEl = document.querySelector("input");
//inputEl.addEventListener(이벤트타입, 이벤트핸들러);
inputEl.addEventListener("keydown", () => {
  console.log("keydown");
});

//화살표 함수에서는 this가 제대로 바인딩 되지 않는다
inputEl.addEventListener("keydown", function (ev) {
  console.log(this);
  console.log(ev);
  console.log("keydown");
});

const buttonEl = document.querySelector("button");
buttonEl.addEventListener("click", function (ev) {
  console.log(this);
  console.log(ev);
  console.log("click");
});

//마우스 객체는 모두 포인터를 받음
profile
멋진 회오리 감자가 되는 그날까지 https://monicx.tistory.com/

0개의 댓글