[DAY 02] JS 주요 문법(2)
[1] 네트워크 기초
브라우저 URL을 입력하면 발생하는 일
[1-1] Step1 URL 해석
- URL은 스키마, 개정정보, 호스트, 포트와 같은 정보로 이루어져 있다.
- URL의 //은 사실 생략 가능 (URL 만든 사람이 멋있어 보여서 추가했다고 함)
[1-2] Step2 DNS 조회
- DNS(Domain Name System)은 도메인과 IP주소를 서로 변환해주는 시스템
- 브라우저는 DNS로 요청 보내기 전에 몇 가지 체크
- 해당 도메인을 알고 있는지 확인(브라우저 캐시 확인)
- 없다면 로컬 컴퓨터의 hosts 파일 참조
- 정의 되어있다면 내부적으로 IP 반환
- 둘 다 해당되지 않는다면 DNS 호출
- present.do, www.present.do, gateway.dev.present.do 전부 도메인은 presnet.do
- 도메인은 present.do, 나머지 서브 도메인이 붙는 경우는 호스트 (도메인 vs. 호스트)
[1-3] Step3 해당 IP가 존재하는 서버로 이동
- 정확히는 해당 IP가 할당된 서버가 존재하는 대역으로 이동
[1-4] Step4 ARP를 이용하여 MAC 주소 변환
- ARP(Address Resolution Protocol): IP 주소(논리 주소)를 MAC 주소(물리 주소)로 변환하는 프로토콜
- 실제 통신을 위해 변하지 않는 고유한 MAC 주소가 필요
- 네트워크 내에 ARP를 Broadcasting하면 해당 IP 주소를 가지고 있는 기기가 MAC 주소를 반환
- IP 주소와 MAC 주소
- IP는 대역을 통해 범위를 좁혀나가는 용도로 사용된다.
[1-5] Step5 TCP 통신을 통해 Socket을 열어야 한다
- 데이터 전달을 위해서는 소켓을 열어야 한다.
- 네트워크를 통해 해당 기기로 패킷 전달
- TCP 연결을 허락받기 위해 3 way handshake로 연결 요청
- 요청이 수락되면 데이터를 서버로 전달하게 되어 기기는 패킷을 받아 처리
[1-6] Step6 서버는 응답을 반환
- HTTP 프로토콜로 들어온 패킷을 읽고 처리
- 요청에 따른 적절한 응답 값을 반환
[1-7] Step7. 브라우저는 렌더링
- HTML을 읽어 DOM Tree 구축
- 만들어진 DOM Tree를 이용하여 화면에 그린다.
- 스크립트 실행
[1-8] 더 알아야 할 것들
- OSI 7 계층
- Routing Table: 통신을 위함
- Subnet mask: IP를 효과적으로 사용하기 위함
- TCP Socket Stream
[1-9] 선택 과제
- http가 이미 있음에도 불구하고 https가 왜 탄생했는지, 왜 필요한지
- https가 생김으로 인해 기존 과정에서 무엇이 추가되었는지
[2] 컴퓨터 시간 원리
[2-1] 컴퓨터가 시간을 표현하는 방법
- 하드웨어의 시스템 클럭 이용
- 시스템 시간
- 특정 시각을 기준으로 시스템 클럭의 틱을 세는 것으로 구현
- RTC(Real Time Clock)라는 모듈을 사용
- RTC는 메인보드에 붙어있어 전원을 끄더라도 계속 작동한다.
- 타임스탬프
- 시스템 시간을 값으로 표현한 것
- 타임스탬프는 운영체제마다 기준 시간과 단위가 다를 수 있다.
- Unix Time
- 유닉스 계열 운영체제에서 시간을 표시하는 방법
- 1970년 1월 1일 0시 0분 0초가 기준 시각(그 이전은 음수)
- 초 단위로 시간이 증가
[2-2] 현재 시간을 알아내는 방법
- 네트워크 타임 프로토콜(NTP) 서버에 네트워크 요청을 하여 현재 시간을 받을 수 있다.
- NTP 서버는 트리구조로 이루어져 있으며, 그 계층을 Stratum이라고 한다.
- 최상위 계층: PRC
[2-3] 컴퓨터에서 시간대 고려하는 방법
- Time Zone 데이터를 DB에 저장하고 받아와 처리
[2-4] JavaScript에서 사용법
- Date 객체 사용
- date-fns, luxon 라이브러리 사용
[3] 암호화 기초
[3-1] 암호화
- 평문을 해독할 수 없는 암호문으로 변화하는 것
- 단방향(해싱) 암호화, 양방향 암호화
[3-2] 단방향 암호화
- 해시 알고리즘을 이용하여 평문을 복호화 할 수 없는 형태로 암호화
- 사용자 비밀번호 등을 저장할 때 사용
- 저장하는 측에서도 해당 데이터를 알면 안되기 때문
- 해킹 당해 암호화된 데이터를 탈취당하더라도 원문을 알아 낼 수 없도록 조치해야한다.
- Salt, Key stretching을 이용해 해결 가능
- Salt: 평문에 임의의 문자열을 추가하여 암호화
- Key stretching: 해시를 여러 번 반복하여 원문을 알기 힘들게 만드는 방법
[3-3] 양방향 암호화
- 평문을 복호화 할 수 있는 형태로 암호화
- 대칭키 알고리즘
- AES
- 같은 키를 이용하여 암호화, 복호화 가능
- 비대칭키 알고리즘
- RSA
- 2가지 키가 존재: 공개키, 개인키
[3-4] JavaScript에서 암호화
crypto-js
[4] 함수형 프로그래밍
[4-1] 함수형 패러다임
- 패러다임은 무엇을 해야 할지를 말하기보다 무엇을 해서는 안 되는지 말해준다.
- 프로그램은 순차, 분기, 반복, 참조로 구성된다.
- 패러다임은 위 4가지 요소를 어떻게 이용할 것인가를 다룬다.
- 함수형 패러다임은 함수가 최소 단위다.→재사용성이 높다. (객체지향에서는 객체)
- 함수형 패러다임은 데이터의 불변성을 지향한다.→동작 예측이 쉽고, 사이드 이펙트를 방지
- 사이드 이펙트를 방지한다: 동시성 문제도 해결된다는 것을 의미
[4-2] 함수형 프로그래밍의 장점→단점
- 상태가 없기 때문에 사이드 이펙트가 없다 → 변수 조작이 안 된다.
- 재사용성이 높다 → 이를 위해 함수를 잘게 쪼개야 하기 때문에 복잡해질 수 있다.
- 코드가 짧고 간결하다 → 많은 숙련도를 요구
[4-3] 선언형 프로그래밍
- 함수형 프로그래밍은 선언형 프로그래밍과 가깝다.
- 기존 명령형 프로그래밍은 문제를 어떻게 해결해야 하는지 컴퓨터에게 명령을 내리는 방법
- 선언형 프로그래밍은 무엇을 해결해야 할지에 집중하고 해결 방법은 컴퓨터에게 위임하는 방법
- 데이터의 제어 없이 필요함수 조합으로 코드 작성 가능
// 명령형 프로그래밍
let a = [1, 2, 3, 4, 5];
for (let i = 0; i < 5; i += 1) {
if (a[i] % 2 === 0) {
console.log(a[i]);
}
}
// 선언형 프로그래밍
[1, 2, 3, 4, 5]
.filter((item) => item % 2 === 0)
.forEach((item) => console.log(item));
### [4-4] 멀티 패러다임
- JavaScript는 멀티 패러다임이 가능하기 때문에, 굳이 객체지향과 함수형으로 나눌 필요 없이 둘 다 사용하는 것이 옳다!
const stringNumber = "12345";
console.log(
stringNumber
.split('')
.map(x => parseInt(x))
.reduce((x,y) => x + y, 0);
);
[5] 객체지향과 프로토타입
[5-1] 객체지향의 객체란?
- 객체지향의 객체는 현실에 있는 것을 추상화한 것
- 현실에 존재하는 것을 코드로 옮기는 것이 아니다!
[5-2] 추상이란?
- 사물이 지니고 있는 여러 측면 중 특정한 부분만 보는 것
- 그 외에 필요없는 부분은 전부 버린다!
- ex) 지구-지도-지구본
- 특정 관점에서 보는 것(모델링이라고도 한다.)
[5-3] 객체지향이란?
- 객체 위주로 설계하고 프로그래밍하는 패러다임
- 객체지향 언어에서 추상화의 최소 단위가 객체다.
- 각각의 객체는 메시지를 주고받을 수 있다.
[5-4] 객체지향의 오해
- 객체지향은 패러다임일 뿐 언어와는 관계가 없다.
- 언어는 지향하는 것을 조금 더 편하게 구현할 수 있게 도와주는 것이므로 클래스가 없는 JS, Go, C언어로도 객체지향 프로그래밍 가능
- JS는 프로토타입을 통해 객체지향을 표현
- 절차지향보다 객체지향이 무조건 더 좋은 것은 아니다.
- 만들어야하는 프로그램에 따라 절차지향이 더 적합할 수 있다.(비교적 간단한 프로그램)
- 객체지향은 객체간 통신하기 때문에 흐름이 더 직관적이어서 더 복잡한 프로그램에 적합
[5-5] 프로토타입
- 자바스크립트의 객체: 클래스 기반 언어처럼 속상과 행위로 정의할 수 있다.
- 객체 생성 방법: 객체 리터럴, Object, 생성자 함수의 3가지 방법 이용
// 객체 리터털
const person = {
name: "김지은",
age: 23,
move : (destination) => {
console.log(`${destination}로 이동합니다.`);
};
};
// Object 생성자
const person = new Object()
person.name = "김지은"
person.age = 23
person.move = (destination) => {
console.log(`${destination}로 이동합니다.`);
};
// 생성자 함수
function Person(name, company, move) {
this.name = name;
this.age = company;
this.move = (destination) => {
console.log(`${destination}로 이동합니다.`);
};
};
- 프로토타입: 기존의 객체를 복사하여 새로운 객체를 생성하는 방식
- 기존 객체를 효율적으로 사용할 수 있다.
- 프로토타입이 필요한 이유: 메모리 낭비 감소
// 프로토타입 사용
function Person(name, company, move) {
this.name = name;
this.company= company;
Person.prototype.getName = function() {
return this.name;
};
Person.prototpye.setName = (name) => {
this.name = name;
};
}
[5-6] 효율적인 프로토타입
- 상속 흉내내기: 부모 객체를 이용하여 프로토타입 함수 정의하기
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name || "지은";
};
function Korean(name) {}
Korean.prototype = new Person();
const kim = new Person("김지은");
const lee = new Korean("이지은");
console.log(kim.getName()); // 김지은
console.log(lee.getName()); // 지은
- 상속 흉내내기: 부모 생성자 빌려쓰기
function Korean(name) {
Person.**apply(this, arguments)**;
}
const kim = new Person("김지은");
const lee = new Korean("이지은");
console.log(kim.getName()); // 김지은
console.log(lee.getName()); // 이지은
- 기존 객체 재활용:
Object.create
const kim = {
name: "김지은",
getName: function () {
return this.name;
},
};
const lee = Object.create(kim);
lee.name = "이지은";
console.log(kim.getName); // 김지은
console.log(lee.getName); // 이지은
[6] 이벤트 루프
[6-1] JavaScript는 대표적인 Single Thread 언어
- JavaScript의 Call Stack은 하나만 존재한다.
- Event Loop를 통해 스크립트가 비동기적으로 데이터를 불러오고 애니메이션을 실행
[6-2] 이벤트 루프
- 이벤트 루프는 JavaScript 엔진에 포함되어 있지 않다.
- 이는 브라우저나 node에서 관리
### [6-3] JS엔진은 싱글 스레드, 브라우저는 멀티 스레드
browser Web API
에 있는 event가 실행되면 자바스크립트에서 실행할callback
함수를Callback Queue
에 저장Event Loop
는Call Stack
이 비어있는지 주기적으로 확인하여 빈 상태가 되면Task Queue
에서Callback function
을 가져와 실행되도록 돕는 역할- 이러한 반복적인 행동을 틱(tick)이라고 한다.
### [6-4] 선택 과제
- 비동기 작업은 Task Queue 뿐만 아니라 Microtask Queue, Animation frames에도 등록됩니다.
각각이 무엇인지 조사해보세요.
[7] 모듈
[7-1] 모듈 탄생 배경
- 예전 JavasScript는 스크립트 파일 간 통신을 위해 전역 스코프에 존재하는 변수와 함수를 사용해야 했다.
- 웹의 기능이 증가하면서 스크립트 파일 증가
- 즉시 실행 함수 등을 통해 전역 스코프가 오염되는 것을 어느 정도 막을 수 있었지만
스크립트 파일 간 의존도를 확인하기 힘들고, 실행 순서를 제어해야 한다는 한계점이 있었다.
- 즉시 실행 함수 등을 통해 전역 스코프가 오염되는 것을 어느 정도 막을 수 있었지만
- 따라서 모듈 등장
- 스크립트 간 의존도를 파악하고 실행 순서 제어 가능
[7-2] 모듈 vs. 컴포넌트
- 모듈: 설계 시점에 의미있는 요소, 의식적으로 나눈 요소
- 컴포넌트: 런타임 시점에 의미있는 요소, 나눠 놓은 요소에 포함되어 실행되는 요소
[7-3] 특징
- 항상 use strict(엄격모드)로 실행된다.
- 모듈 레벨 스코프가 있다.
- 모듈은 최상위에 변수를 선언해도 전역스코프에 올라가지 않고 ****자체적인 모듈 레벨 스코프에 올라간다.
- 일반 스크립트는 최상위에 선언하면 전역 스코프에 선언돼 다른 스크립트에서도 참조가 가능하지만 모듈 스크립트에서는
import
하지 않으면 참조 불가능
- 단 한 번만 평가된다.
- 지연 실행된다.
- 모든 돔이 만들어진 후에 실행
요즘은 Webpack과 같은 모듈 번들러를 사용하기에 type=”module”을 사용할 일이 적다.
[8] 유니코드
[8-1] 브라우저는 다양한 문자를 표현할 수 있다.
- 값으로 이루어진 문자 + 글꼴 → 렌더링 엔진 통해 그려짐
[8-2] 문자 시스템
- CCS(Coded Character Set)
- 문자들을 Code Point에 대응시켜 만든 코드화된 문자들의 집합
- Character의 식별자가 된다.
- CES(Character Encoding Scheme)
- CCS를 octect(8bit) 집합에 대응시키는 것
- CCS와 CES는 1:1 대응
- 인코딩에 해당
- 인코딩: Character를 시스템이 인식할 수 있는 값으로 변환
- 디코딩: 인코딩된 값을 다시 Character로 변환
- TES(Transfer Encoding Syntax)
- 인코딩한 문자가 특정 프로토콜을 타고 전송되도록 변환
- 통신 프로토콜에 제약이 있을 수 있기 때문
- ex) URL에서 공백은 사용할 수 없기 때문에 변환해야 한다.
[8-3] 유니코드
- 전 세계 문자를 컴퓨터에서 다룰 수 있도록 만든 표준 시스템
- 다양한 나라가 서로 다른 인코딩 방식을 사용해 발생했던 문제를 해결
- 대부분의 문자 포함, 이모티콘도 포함
[9] 정규표현식
[9-1] 정규표현식의 목적
[9-2] 정규표현식 표현
/regexr/i
- / : 시작, 종료 기호
- regexr : 패턴
- i : 플래그
[9-3] JavaScript에서의 정규표현식
- RegExp 객체로 정규표현식 기능 제공
- Array, Object 처럼 Literal로 생성 가능
// 생성자 함수 방식
const regExp1 = new RegExp("^\+");
const regExp1 = new RegExp("^\+", "gi");
// 리터럴 방식
const regexp1 = /^\d+/;
const regexp1 = /^\d+/gi;
test
: 입력받은 문자열에 찾는 패턴이 있는지 찾은 후 True or False 반환exec
: 입력받은 문자열에 찾는 패턴이 있는지 찾은 후 일치한 패턴 정보를 반환하고 없으면 null 반환match
: String객체의 match 함수는 정규표현식 객체를 파라미터로 받아 패턴이 있는지 찾은 후 일치한 패턴 정보를 반환하고 없으면 null 반환, 정규표현식의 exec와 동일, 문자 추출에 해당replace
: String객체의 replace함수는 정규표현식 객체를 파라미터로 받아 패턴이 있는지 찾은 후 일치한 패턴 정보를 원하는 문자열로 바꿔줌search
: 매칭된 문자열의 위치 반환, 무조건 처음 매칭된 것을 반환capture
: 원하는 부분 캡쳐
[9-4] 선택 과제
- 개미 수열을 정규표현식을 이용해 풀어보기
- 5를 입력받으면 “111221”이 나와야 한다.
- 힌트: Run-length encoding
[10] 쿠키와 세션, 웹 스토리지
[10-1] HTTP 통신
- 기본적으로 상태가 존재하지 않는다.(stateless)
- 따라서 서버는 요청이 어떤 브라우저에서 온 것인지 알 수 없다.
- 이 때 헤더에 쿠키를 담으면 서버가 쿠키를 읽어 어디서 온 것인지 알 수 있다.
[10-2] Cookie
- 클라이언트에서 저장, 관리하는 데이터들
- 서버에서 Set-Cookie 를 응답 헤더로 내려주면 클라이언트는 받아서 저장한다.
- 클라이언트에서 자체적으로 조작 가능 및 각 상태에 수명을 정할 수 있다.
- 각 상태에 수명을 정해줄 수 있다.
[10-3] Set-Cookie
- 서버에서 내려주는 것으로 응답 헤더에 담으면 브라우저가 알아서 저장
- 각 데이터에는 여러 옵션이 존재
-Expires
: 쿠키 만료 날짜 지정
-Secure
: HTTPS에서만 쿠키 전송
-HttpOnly
: JavaScript에서 쿠키 접속 못하도록
-Max-Age
: 쿠키 수명 지정, 이때 Expires는 무시됨
-Domain
: 도메인이 일치하는 요청만 쿠키 전송
-Path
: 패스와 일치하는 요청만 쿠키 전송
[10-4] 쿠키의 취약점
- XSS(Cross-Site-Script) 공격을 당할 수 있다.
- JS를 이용해 다른 사용자의 쿠키 값을 탈취하는 것
- 쿠키를 암호화하지 않고 보내면 쿠키값을 중간에 탈취 당할 가능성이 있다.
- HTTPS로 해결 가능
[10-5] Session
- 서버가 사용자를 구분하는 방법
- HTTP Session Id를 식별자 사용
- 클라이언트: HTTP Session Id를 쿠키 형태로 저장
- 서버: 자체적으로 기록, 관리
- 문제점
- 사용자가 많아졌을 때의 서버 관리
- 서버가 2대일 때의 세션 관리
- 따라서 이제는 서버와 클라이언트간 인증은 별도 토큰을 사용하고, 쿠키는 클라이언트 자체적인 지속적인 데이터 관리 용도로 많이 사용된다
[10-6] 웹 스토리지
- 쿠키 대신 로컬 데이터 관리, 쿠키가 하기 힘든 것들을 지원
- 로컬 스토리지
- 데이터를 저장하면 반영구적으로 데이터가 저장됨
- 브라우저를 종료해도 계속해서 데이터가 남는다.
- 쿠키와 마찬가지로 Key-Value 형태로 저장됨
- 세션 스토리지
- 새 창을 생성할 때마다 개별적으로 저장되는 데이터 관리
- 브라우저를 닫는 순간 사라진다.
- 같은 도메인이어도 세션이 다르면 데이터에 접근할 수 없다.
- 쿠키와 마찬가지로 Key-Value 형태로 저장됨
[10-7] 추가 공부
- IndexedDB
- Transacrional한 로컬 DB
- 새로운 웹 브라우저 표준 인터페이스
Author And Source
이 문제에 관하여([DAY 02] JS 주요 문법(2)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@jieun0411/DAY-02-JS-주요-문법2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)