Node.js 재생 목록
https://www.youtube.com/playlist?list=PLcqDmjxt30RsGIPBBKX7xl05VuqJeCTFn
2장
2.1 호출 스택, 이벤트 루프
1. 호출 스택
- 함수를 선언했다는 것은 메모리(임시 저장장치)에 올렸다는 뜻.
- Anonymous는 가상의 전역 컨텍스트로 항상 맨 밑에 있다고 생각하자.(크롬에서 나오는 단어)
- 함수는 호출 순서대로 쌓이고, 역순(가장 위부터)으로 실행된다.
- 함수 실행이 완료되면 바로 스택에서 빠진다.
=> LIFO구조
* 동기란? 간단히 순서대로 실행되는 구조라고 할 수 있음.
- 일단 호출부터 하기 때문에 호출 스택만으로는 자바스크립트를 온전히 설명할 수 없음
=> 호출 스택 + 이벤트 루프
*자바 스크립트의 호출 원리*
=> 호출 스택, 백그라운드, 테스트 큐, 메모리, 콘솔 창
1. 호출 스택으로 들어온 함수 처리
2. 비동기 함수는 백그라운드로 코드를 보냄
(코드가 백그라운드로 가게 되면 호출스택과 백그라운드가 동시 실행된다.)
(백그라운드 처리가 먼저 끝나도 항상 호출 스택이 먼저 처리되어야 한다.)
(백그라운드는 동시 실행이 되므로 비동기적)
(백그라운드는 다른 스레드가 실행한다.)
(백그라운드로 보낼 수 있는 코드들이 정해져 있음.(제한적))
(백그라운드에서 동시 실행될 수 있는 이유는 자바스크립트가 아님~)
3. 백그라운드는 테스트 큐에 해당 코드를 보내면서 백그라운드는 비워져야 한다.
4. 이벤트 루프의 역할은 호출 스택이 비어있을 때,
테스트 큐에 들어있는 함수 하나하나를 가져와서 호출 스택에 쌓아 실행하는 역할을 한다.
5. 호출 스택, 백그라운드, 테스트 큐가 다 비워지면 자바 스크립트 실행 완료!
2.2 var, const, let
1. const, let
- ES2015 이전에는 var로 변수 선언 (함수 스코프)
* variable은 블록 스코프(중괄호)를 무시할 수 있어서 블록 밖에서도 변수 접근이 가능
* 그러나 function 블록은 무시를 못 함.
- const, let => 블록 스코프
- const: 값을 한 번만 넣을 수 있다. 이후 수정 불가능 그러나 객체 수정은 가능
- let: 값 수정 가능!
- 사용 예시
const a = 3;
a = '10'; // 에러
const b = {name:'jinsol'};
b.name = 'sol'; // 수정 가능
var won = 1000;
var result = '이 과자는 ' + won + '원 입니다.';
=> 웬만하면 const로 값 설정을 하고 값 바꿀 일이 생기면 let으로 수정하자.
2.3 템플릿 문자열, 객체 리터럴
1. 템플릿 문자열
=> const result = `이 과자는 ${won}원 입니다`; // 한 번에 작성 가능
- (`) 백틱을 사용하여 문자열 작성 (백틱은 함수 호출 기능도 있음)
(ex) function a() {} 의 함수 호출시 a``;로 호출 가능)
- ${}로 변수 사용 가능
2. 객체 리터럴
- 객체 메소드에 :function 사용 안 함.
- [변수 + 값 ] 등으로 동적 속성명을 객체 속성명으로 사용 가능
2.4 화살표 함수
화살표 함수는 function을 완벽하게 대체할 수 없다.
// add~는 다 같은 함수
function add1(x, y) { return x + y; }
const add2 = (x, y) => { return x + y; }
const add3 = (x, y) => x + y; // 중괄호 뒤에 *바로* return이 나오면 생략 가능!
const add4 = (x, y) => (x + y);
const obj = (x,y) => ({x, y}); // 객체를 리턴하는 경우에만 소괄호 필수 작성
function not1(x) { return !x; } // 매개 변수가 하나인 경우에도 생략 가능!
const not2 => !x;
기존 function이 사라지지 않은 이유: this
=> function()에서는 this를 따로 갖는 반면 (자신만의 this), 화살표 함수는 부모의 this를 따라간다.
var relationship1 = {
name: 'mine',
friends: ['one', 'two', 'three'],
logFriends: function() {
var that = this;
this.friends.forEach(function (friend) {
console.log(that.name, friend);
});
},
};
relationship1.logFriends();
var relationship1 = {
name: 'mine',
friends: ['one', 'two', 'three'],
logFriends: function() {
var that = this;
this.friends.forEach(function (friend) {
console.log(this.name, friend);
});
},
};
relationship1.logFriends();
// 출력결과가 다름을 이해해야 함.
var relationship2 = {
name: 'mine',
friends: ['one', 'two', 'three'],
logFriends() {
this.friends.forEach(friend => {
console.log(this.name, friend);
});
},
};
relationship2.logFriends();
// 화살표 함수는 그대로 부모의 this를 물려받음.
function ()과 화살표 함수는 구분해서 잘 사용하기.
2.5 구조분해 할당
속성 이름을 변수 이름으로 만들어주는 상황이 많이 발생한다.
this가 있는 경우에는 구조분해를 안 하는 것이 낫다.
//과거
const example = { a: 123, b: { c: 456, d: 789 } }
const a = example.a;
const d = example.b.d;
//현재
const { a, b: { d } } = example;
console.log(a); //123
console.log(d); //789
//과거
arr = [1, 2, 3, 4, 5]
const x = arr[0]
const y = arr[1]
const z = arr[4]
//현재
const[x,y,,,z] = arr;
//해당 위치에 값을 정해서 넣어준다는 뜻
// 0, 1, 4번째 자리에 값을 넣어주고 나머지는 빈 값으로 배열 생성
2.6 클래스
- 클래스는 프로토타입.
- 프로토타입 문법을 깔끔하게 작성할 수 있음.
- Constructor(생성자), Extends(상속) 등을 깔끔하게 처리할 수 있음.
- 코드 그룹화 => 가독성 향상!
* 생성자 함수는 주로 첫글자 대문자로 선언
* 생성자 메소드, static 메소드, 인스턴스 메소드를 한번에 그룹화
* extends를 사용하여 상속
2.7 프로미스
- 내용은 실행되었지만 결과는 아직 반환되지 않은 객체
- 어떤 동작을 하게 요청함.
- Then을 붙이면 결과를 반환
- 실행이 완료되지 않았다면 완료된 후 Then의 내부 함수가 실행 됨
! Resolve( 성공 값 ) -> then 으로 연결
! Reject( 실패 값 ) -> catch 로 연결
! Finally 부분은 무조건 실행
=> 코드 분리가 가능하여 콜백 헬을 막을 수 있다.
* Async/await(에이싱크 어웨잇)으로 프로미스 패턴 코드 축약도 가능.
=> 실행 순서가 오른쪽 -> 왼쪽
=> 변수 = await 프로미스; : 프로미스가 resolve된 값이 변수에 저장된다.
==> await이 then이 되어 처리됨.
=> 변수 = await 값; : 그 값이 변수에 저장 됨.
=> async도 결론은 promise
=> 사용 예시
const promise = new Promise(...)
promise.then((result) => ...)
async function main() {
const result = await promise; }
main();
// 옛날에는 async function으로 감싸줘야 했음.
// 현재는 const result = await promise; 한 줄로 가능.
async function main() {
try {
const result = await promise;
return result ;
} catch (error) {
console.error(error);
} }
main().then((name) => ... ) // 1. async에서 return 값은 then으로 받아야 한다.
const name = await main() // 2
2.8 Map/Set 객체
* Map은 객체 리터럴과 비슷함. {'a': 'b'} //키, 값으로 구성
- Map은 키와 값을 각각 객체로 전달할 수 있음.
ex) m.set( { a: 'b' }, { c: 'd' } )
get으로 가져오고 싶을경우 해당 키를 변수로 저장하여 사용
ex) const obj = { key: 'key' }
m.set(obj, 123)
m.get(obj)
- 반복문은 for (const [k, v] of m) 으로 사용
- Map 은 size도 가져올 수 있음. => m.size (length)
- m.forEach(v, k) => { ... } 로도 사용 가능
- has(), delete() 메소드를 사용하여 속성 존재 여부 및 속성 삭제
- Map은 속성들 간 순서를 보장하고 반복문을 사용할 수 있다.
- WeakMap은 가비지 컬렉팅이 가능
* Set은 배열 리터럴과 비슷함. []
- 배열을 완전 대체하기는 힘듦.
- 중복을 허용하지 않음. (자료형이 다른 경우는 별개로 인식)
- 기존 배열에서 중복을 없애고 싶을 때 사용함.
2.9 null 병합/옵셔널 체이닝
* null 병합 연산자(??)
- null 병합 연산자(??) 는 주로 ||(또는) 연산자 대용으로 사용
- falsy 값(0, '', false, NaN, null, undefined) 중 null과 undefined만 따로 구분
- || 연산자는 falsy 값이면 뒤로 넘어간다.
cf) &&(AND) 연산자는 true 값일 때 뒤로 넘어간다.
ex) const a = 0;
const b = a || 3;
console.log(b); // 3
- ?? 연산자는 *null과 undefined*일 때만 뒤로 넘어간다.
ex) const c = 0;
const d = c ?? 3;
console.log(d); // 0
* 옵셔널 체이닝 연산자(?.)
- null이나 underfined의 속성을 조회할 때 에러를 막음.
- 사용 ex) c?.d // c?.f() // c?.[0]
=> c가 없으면 없는대로 놔두고, 있다면 d를 읽는다.
2.10 프런트엔드 자바스크립트
1. AJAX : 서버로 요청을 보내는 코드
- 라이브러리 없이 브라우저가 지원하는 XMLHttpRequest 객체 사용
- AJAX 요청 시 Axios 라이브러리를 사용하는 것이 편함.
=> Axios는 프로미스를 지원함.
- HTML 아래 스크립트를 추가하여 사용할 수 있음.
<script src="https://unpkg.com/axios/dist/axios.min.js" />
2. FormData
- HTML form 태그에 담긴 데이터를 AJAX 요청으로 보낼 때
- FormData 객체 이용
- Form 메소드
1. append()로 데이터 추가
2. has()로 데이터 존재 여부 확인
3. Get()으로 데이터 조회
4. getAll()로 데이터 모두 조회
5. delete()로 데이터 삭제
6. set()으로 데이터 수정
3. encodeURIComponent, decodeURIComponent
- 주소창 한글 입력 => 서버 처리 오류
=> encodeURIComponent로 한글 감싸서 처리
=> decodeURIComponent로 서버에서 한글 처리
4. data attribute와 dataset
- HTML 태그에 데이터를 저장하는 방법
1) 서버의 데이터를 프런트엔드로 내려줄 때
2) 태그 속성 data-속성명
3) 자바스크립트에서 태그.dataset.속성명으로 접근 가능
ex) data-user-page -> dataset.userPage (data제외 두번째부터 대문자)
data-nickname -> data.nickname
4) dataset에 값을 넣으면 data-속성이 생김 (3과 반대)
ex) dataset.money = 500 -> data-money = "500"
=> 이 값은 누구나 꺼낼 수 있으므로 공개 데이터에만 사용해야 한다.
끝!
2장 복기..
호출 스택은 함수를 임시 장치에 올리는 것.. LIFO 구조
동기는 순서대로 처리되는 구조, 비동기는 순서X but 나름의 규칙 존재
비동기와 동기 함수의 처리 과정이 다르다.
비동기 함수에는 setTimeout(), 동기 함수에는 resolve(), Promise()등이 있다.
Promise() 함수는 then을 만나는 순간 비동기 함수로 처리한다.
(Promise()의 then은 우선순위가 높아서 테스트 큐에서 먼저 처리될 수도 있다.)
resolve() 함수는 내부까지 동기이므로, 내부까지 들어가서 실행을 하는데,
비동기 함수는 백그라운드로 코드를 보내줘야한다.
var, const, let의 변수 선언
var는 옛날 방식
const는 한 번 선언하면 값 수정 불가. 그러나 객체 수정은 가능
let은 수정 가능~
화살표 함수를 사용하는데 function ()과 잘 구분해서 사용 ~
구조분해할당이 있는데 쪼개서 각각에 할당하여 사용하는 것.
Map은 객체 리터럴과 비슷, 키와 값으로 이루어져 있다. 키와 값은 객체형태도 가능.
Set은 배열 리터럴과 비슷, 중복을 허용하지 않는다.
WeakMap은 가비지 컬렉팅이 가능해서 빈 객체를 선언한 변수를 키 값으로 사용한 뒤,
나중에 객체를 null;로 선언하면 객체 삭제가 가능하고, 객체를 수정하지 않으면서
값을 추가할 수도 있지만 원래 Map은 삭제가 되지 않고 메모리에 그대로 남아있다.
옵셔널 체이닝은 널 병합 연산자와 같이 쓰면 좋다.
비동기는 실패할 환경까지 생각해둬야 한다.
프로미스 지원 함수인지 콜백 지원 함수인지 알아야 함. => 공식문서 보고..