일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 자바스크립트강의 후기
- 더오름
- dreamhack reversing
- 드림핵 리버싱
- 안드로이드 adb start-server
- adb 옵션
- 리버싱 핵심 원리
- 제주코딩베이스캠프
- 리버싱 플래그
- 자바스크립트 강의 추천
- 안드로이드 모바일 앱 모의해킹
- 자바스크립트 강의
- 안드로이드 adb
- 리버싱 스터디
- 리버싱 초보
- 리버싱
- 자바스크립트
- 강의 체험단 1기
- rev-basic 풀이
- 리버싱 입문
- 티스토리챌린지
- 드림핵 플래그
- 위니브
- 제주ICT
- 인프런 강의 추천
- 안드로이드 리버싱
- 오블완
- 리버싱핵심원리
- 드림핵 리버싱 풀이
- adb
- Today
- Total
해보자고
[UDEMY] Node.js - Section(02) 본문
Javascript 요약
*약타입 프로그래밍 언어이며 객체 지향 프로그래밍 언어.
약타입 프로그래밍 언어라는 점에서 엄격한 타입 설정은 필요 없으나 오류로 이어질 수 있다.
객체 지향 프로그래밍 언어라는 점에서 *원시 타입(Primitive type), *참조 타입(Reference Type)의 차이를 알아야 한다.
Node.js를 통해 브라우저 밖의 서버 등의 다양한 환경에서 실행이 가능하다.
*약타입 언어: 명확한 타입 할당이 없다.
+) string, boolean 등의 타입이 있지만 변수 또는 함수에서 어떤 형태를 사용하는지 정의하라고 강요하지 않고, 타입을 동적으로 변경이 가능하다. ex) 숫자 변수 -> 문자 변수
*원시 타입: string, number, boolean 등과 같이 실제 데이터 값을 저장하는 타입
*참조 타입: 원시 타입을 제외한 나머지 타입이며, 객체의 번지를 참소하는 타입 즉 메모리 상의 주소를 통해 객체를 참조하는 타입을 의미.
Javascript 복습
변수
var name = 'Max'; //문자
var age = 29; //숫자
var hashobbies = true; //Boolean
// line 1 ~ line 3은 전역 변수
function summerizeUser(userName, userAge, userHasHobby) { // function 키워드로 함수 정의, 로컬 변수로 함수 안에서만 사용 가능.
return ( // return 통해 값 반환
'Name is ' +
userName +
', age is ' +
userAge +
', and the user has hobbies: ' +
userHasHobby
);
}
console.log(summerizeUser(name, age, hasHobbies)); // 함수 호출
// line 7 ~ line 18 은 외부에 의존하지 않는 순수 함수로 데이터 모두 인수 형태로 받고 있음.
=> 결과 값
let 과 const
변수를 생성하는 키워드들이지만 차이점이 존재.
차이점
- let은 값의 업데이트가 가능하지만 const는 값의 업데이트가 불가능.
- 즉, 변수 값의 변경 계획 여부에 따라 const와 let을 사용.
const name = 'Max';
let age = 29;
const hasHobbies = true;
name = 'Mazimilian'; // 에러 유발 <- const로 선언했는데 값을 바꿔서
age =30;
function summerizeUser(userName, userAge, userHasHobby) {
return (
'Name is ' +
userName +
', age is ' +
userAge +
', and the user has hobbies: ' +
userHasHobby
);
}
console.log(summerizeUser(name, age, hasHobbies));
화살표 함수
익명 함수
- 함수를 정의하는 또 다른 방법
- 익명 함수는 function 다음에 이름을 설정하는 것이 아니라 (ex. function a1 = {};) 익명 함수를 명명된 const에 저장하여 기명 함수로 만들어 줌.
const summerizeUser = function (userName, userAge, userHasHobby) { // 변경 코드. function 부터 끝까지 익명 함수
return (
'Name is ' +
userName +
', age is ' +
userAge +
', and the user has hobbies: ' +
userHasHobby
);
}
화살표 함수
- function 키워드가 없기에 좀 더 짧고 이전 방식과 마찬가지로 함수 작동.
const summerizeUser = (userName, userAge, userHasHobby) => { // function 키워드를 제거하고 인수 목록과 중괄호 사이에 화살표를 추가
return (
'Name is ' +
userName +
', age is ' +
userAge +
', and the user has hobbies: ' +
userHasHobby
);
};
- 화살표 함수 실습 1
const add = (a,b) => {
return a+b;
};
console.log(add(1,2));
// 결과 값: 3
----------
const add = (a,b) => a+b;
console.log(add(1,2));
// 결과 값: 3
- 화살표 함수 실습 2
- return문이 하나만 있는 화살표 함수라면 중괄호와 return 생략 가능.
- 즉 위 함수와 아래 함수는 동일한 구문
const addOne = (a) => a + 1;
console.log(addOne(1));
// 결과 값: 2
---------
const addOne = a => a + 1;
console.log(addOne(1));
// 결과 값: 2
- 화살표 함수 실습 3
- 인수가 하나라면, 인수 이름을 입력하고 괄호가 없어도 있을 때와 동일하게 작동함.
- 둘 모두 가능하지만 일반적으로는 괄호 없는 구문을 사용함.
const addRandom = () => 1 + 2;
console.log(addRandom());
// 결과 값: 3
- 인수가 없는 화살표 함수가 있으면 비어있는 괄호 한 쌍을 명시해야 함. 즉 공백으로 두면 안 됨.
객체와 속성 및 메소드
객체 생성
- 일반적으로 중괄호를 통해 객체 생성
- 중괄호 안에는 키-값 쌍이 들어감. (프로퍼티 또는 필드라고도 불림)
- 객체를 통해 데이터 묶기가 가능.
const person = { // person이 객체
name: 'Max', // :이 꼭 필요하다.
age: 29
};
console.log(person);
// 결과 값: { name: 'Max', age: 29 }
const person = {
name: 'Max',
age: 29,
greet: () => {
console.log('Hi, I am ' + this.name); //this는 주위 객체를 참조하며, 마침표를 사용함. '.'으로 속성 또는 매서드, 즉 객체 내의 변수나 함수를 액세스.
}
};
person.greet();
// 결과 값: Hi, I am undefined
- 객체에 변수 뿐 아닌 함수도 넣는 것이 가능
- 결과 값이 Hi, I am undefined인 이유 => 화살표 함수의 특성 때문. this는 이제 person 객체가 아닌 전역 범위, 전역 노드 런타임 범위를 참조. 이를 참조하도록 하려면 기존 function 키워드를 사용해야 함. (아래 코드 참조)
const person = {
name: 'Max',
age: 29,
greet: function() { // 변경 코드
console.log('Hi, I am ' + this.name);
}
};
person.greet();
// 결과 값: Hi, I am Max
- 또는 화살표 함수 사용 X, 키와 괄호 사이의 콜론을 생략하고 바로 함수 본문 입력 => 메서드가 됨. (아래 코드 참조)
const person = {
name: 'Max',
age: 29,
greet() { // 변경 코드
console.log('Hi, I am ' + this.name);
}
};
person.greet();
// 결과 값: Hi, I am Max
배열과 배열 메서드
배열
- 대괄호로 정의
- 참조타입
- 어떤 데이터든 배열에 담길 수 있음.
- 배열에 하나의 데이터 타입만을 사용할 필요 없음.
const hobbies = ['sports', 'Cooking', 1, true]; // 가능
for 루프와 배열
const hobbies = ['sports', 'Cooking'];
for (let hobby of hobbies) { // 매 반복마다 각 원소를 hobby 변수로 저장
console.log(hobby);
}
- hobbies에 두 개의 원소가 있기에 console.log는 2번 실행됨.
- 매 반복마다 값이 바뀌며, 왼쪽에서 오른쪽으로 진행.
- 배열에는 다양한 내장 메서드가 존재.
- 확인 방법| 배열명.
map
- 배열 또는 값들을 변환해주며 새로운 배열을 반환함. -> 기존의 것을 편집하는 대시 새로운 배열을 반환.
- 함수의 형태이며, 어떻게 배열 혹은 배열의 원소를 편집할지 정의해야 함.
- 배열의 모든 원소에 하나씩 적용되며 업데이트된 원소가 새로운 배열에 반환.
const hobbies = ['sports', 'Cooking'];
console.log(hobbies.map(hobby => 'Hobby: ' + hobby)); // 새로운 배열
console.log(hobbies); // 기존 배열
- 결과를 보면 기존 배열이 편집된 것X.
- map을 통해 편집된 새로운 배열을 결과로 확인 가능.
push
- 기존 배열에 새로운 원소를 추가할 수 있음.
const hobbies = ['sports', 'Cooking'];
hobbies.push('Programming');
console.log(hobbies);
// 오류 발생XX
- 배열은 참조타입이므로, const로 배열을 선언해도 그 값을 바꾸는 것이 가능.
why?
- 배열이 저장된 메모리 위치를 가리키는 주소만 저장하기에 새 원소를 추가해도 주소를 나타내는 포인터가 바뀌지는 않았기 때문에.
- 즉 const 값이 바뀐 것 X
Spread 및 Rest 연산자
불변성
기존 배열을 편집하지 않고, 기존 값과 새로운 값이 모두 포함된 새로운 배열을 만드려는 패턴. 즉 사본에 변경된 값을 더한 배열로 기존 객체를 편집하지 않고서, 편집 가능. 이는 곧 오류를 적게 일으킬 수 있음.
Slice 연산자
- slice()
- 배열을 복사함.
- 인수를 입력하여 복사하길 원하는 원소의 범위를 제한할 수 있음. (인수가 없다면 배열 전체를 복사함.)
중첩 배열
- 대괄호로 새로운 배열을 만들고 hobbies를 추가
const copiedArray = [hobbies];
console.log(copiedArray);
- 실제로는 배열 안에 또 다른 배열이 있는 것임. 즉 외부 배열에 하나의 원소만이 있고 그 원소가 바로 내부 배열.
- 따라서 사본이 아니라 첫 원소가 기존의 배열인 새로운 배열인 것.
- 이는 사본이 아니라 완전히 동일한 객체를 의미함.
Spread 연산자
- 배열 또는 객체 앞에 점 세 개 추가하기.
- 연산자 뒤에 오는 배열, 객체 등을 받아서 원소 또는 속성을 끄집어 냄.
const person = {
name: 'Max',
age: 29,
greet() {
console.log('Hi, I am ' + this.name);
}
};
const copiedPerson = {...person}; // 기존 객체의 원소를 모두 추출해서 새로운 객체에 추가.
console.log(copiedPerson);
const hobbies = ['sports', 'Cooking'];
const copiedArray = [...hobbies]; // 스프레드 연산자에 대괄호가 씌워져 있음 -> 기존 배열에서 끄집어낸 모든 원소를 새로운 배열에 추가해 준다는 의미.
console.log(copiedArray);
- ['sports', 'Cooking'] 은 기존 배열의 사본임.
- { name: 'Max', age: 29, greet: [Function: greet] }은 기존 객체의 사본임.
Rest 연산자
- 배열 또는 객체 앞에 점 세 개 추가하기.
- 구문으로 보면 스프레드 연산자와 동일하지만 사용하는 위치에 따라 정의가 달라짐.
- 스프레드 연산자와 레스트 연산자의 구분:
스프레드 연산자 | 배열이나 객체에서 원소나 속성을 추출하는 데 사용 |
레스트 연산자 | 인수 목록이나 함수에서 여러 인수를 하나의 배열로 묶는데 사용 |
- Rest 연산자 예시:
const toArray = (arg1, arg2, arg3) => {
return [arg1, arg2, arg3];
}
console.log(toArray(1,2,3,4));
// 결과 값: [ 1, 2, 3 ]
- 유연한 코드는 X => 인수로 3개의 값을 전달할 때는 괜찮은데, 지정한 인수 값을 넘어서면 추가된 인수는 추가되지 않음.
const toArray = (...args) => { // 인수 개수에 관계없이 모든 인수를 가지고 와서 하나의 배열로 나타낼 수 O
return args;
}
console.log(toArray(1,2,3,4));
// 결과 값: [ 1, 2, 3, 4 ]
Destructuring
들어오는 객체에서 무엇을 필요로 하는지, 어떤 값을 로컬 변수에 저장해서 이 함수에 사용할지 확실히 명시함으로써 이해하기 쉬운 코드를 작성하는데 도움이 되는 구문.
객체나 배열 내의 원소를 액세스하거나, 이름 또는 위치에 따라 무시하게 해줌. -> 이는 삭제와는 달라서 삭제되는 것이 아니며 우리가 작성하는 함수 또는 대상에 사용되지 않는 다는 뜻.
함수 안
- name 속성만이 필요한 코드가 필요하다고 생각.
- 객체에서는 속성 이름으로 이 값들을 추출.
// <<Destructuring 이용XX>>
const person = {
name: 'Max',
age: 29,
greet() {
console.log('Hi, I am ' + this.name);
}
};
const printName = (personData) => {
console.log(person.name);
}
printName(person);
// 결과 값: Max
// <<Destructuring 이용O>>
const person = {
name: 'Max',
age: 29,
greet() {
console.log('Hi, I am ' + this.name);
}
};
const printName = ({name}) => { // . 다른 속성은 무시되며 이 속성은 name이라는 변수로 저장되어 사용할 수 있음.
console.log(name);
}
printName(person);
// 결과 값: Max
- 인수 목록에 {}(중괄호) 추가하여 관심있는 객체 속성을 명시.
함수 밖
const person = {
name: 'Max',
age: 29,
greet() {
console.log('Hi, I am ' + this.name);
}
};
const printName = ({name}) => {
console.log(name);
}
printName(person);
const { name, age } = person; // name과 age 값이 저장된 새로운 const가 생성. person의 속성명과 입력한 값이 일치해야 함.
// 윗 줄: 일반적으로는 틀린 문법이지만 구조 분해에서는 올바른 방법
console.log(name, age);
// 결과 값: Max 29
배열 구조 분해
const hobbies = ['sports', 'Cooking'];
const [hobby1, hobby2] = hobbies; // hobby1과 hobby2를 대괄호로 묶은 const를 생성하고 이를 hobbies에 할당.
console.log(hobby1, hobby2); // 배열을 기록하게 하지 않아서 대괄호가 없음.
// 결과 값: sports Cooking
- 객체 구조 분해와 다르게 배열 구조 분해에서는 원하는 이름을 선택할 수 있다.
WHY?
- 배열에서는 원소들에 이름이 없고 위치를 기반으로 추출되기 때문. 따라서 hobby1은 항상 첫 번째 원소, hobby2는 항상 두 번째 원소.
비동기 코드와 프로미스
비동기 코드
예시 1)
setTimeout(() => { // 내장된 타이머 함수. 1번째 인수는 할 내용, 2번째 인수는 타이머(<- 밀리초로 표현해야 해서 2초 = 2000 밀리초.)
console.log('Timer is done!');
}, 1); // 비동기 코드
console.log('Hello!'); //동기 코드
console.log('Hi!'); //동기 코드
- 비동기화 코드는 1밀리초로 아무리 빠른 시간이라도 즉시 끝나지 않기 때문에 비동기화 코드임.
- 두 console.log 스니핏은 하드웨어를 제외하고는 딜레이가 존재하지 않으므로 동기화 코드.
- 결과 값으로 Hello, Hi! 가 Timer is done! 보다 빠르게 나오는데 이는 Node.js와 Javascript가 일반적으로 코드 실행이 종료될 때까지 기다리지 않는다. 즉, setTimeout() 에서 콜백 함수라고 하는 함수를 인식 -> 모든 동기화 코드를 실행 -> 비동기화 코드가 실행.
예시 2)
const fetchData = (callback) => {
setTimeout(() => {
callback('Done!');
}, 1500);
};
setTimeout(() => {
console.log('Timer is done!');
fetchData((text) => {
console.log(text);
});
}, 2000);
console.log('Hello!');
console.log('Hi!');
- 중첩된 비동기화, 콜백함수를 사용할 때의 몇 가지 문제점. (인데,, 잘 안 쓴다고 하는데 호호 이해가 안되네.)
프로미스
'웹 프로그래밍' 카테고리의 다른 글
PBL4 - 코드 분석 (0) | 2023.09.14 |
---|---|
[UDEMY] Node.js - Section(03) (0) | 2023.08.24 |
[UDEMY] Node.js - Section(01) (0) | 2023.07.07 |
[javascript] 생활 코딩 스터디 1주차 (1) [정리] (0) | 2023.03.12 |