JavaScript 기본
시작하기 전에....
Javasript는 개발 도중 문제를 일으킨 명령어들이 꽤나 있었던 것으로 보인다.
때문에 지금은 거의 사용하지 않는 명령어들이 있다.
얘네들이 있음을 인지하고 쓰지 않도록 하자
여기서 배워가는 것
변수
비교연산자
자료형
조건문
반복문
논리연산자
함수
구조분해 할당
동기와 비동기
Blocking과 NonBlocking
Promise
비동기함수
await연산자
■변수
변수의 종류: var, let, const
대충 이런것들이 있다는 것만 알면 된다.
원래는 var만 있었지만 이게 문제아라서 let과 const라는 새로운 모범생이 추가된 것이다.
그러니까 var은 쓰지 말자
var | 문제아 |
let | 값을 다른 값으로 바꿀 수 있다 |
const | 값을 바꿀 수 없다! |
■비교연산자
비교연산자의 종류: ===, !==, >, <, >=, <=, ==, !=
=== | 좌우의 값이 같으면 true, 다르면 false로 한다. |
!== | 위와는 정반대로 좌우의 값이 같으면 false, 다르면 true로 한다. |
>, <, >=, <=, = | 수학에서 말하는 초과, 미만, 이상, 이하와 같다. 좌우가 같다면 =을 사용한다. |
==, != | 위에 설명한 ===와 !==와 같은 기능하지만 여러가지 문제가 있으므로 사용하지 않도록 한다. |
■자료형
색이 있는 칸은 후술한다.
Boolean | 참, 거짓 형 자료형(true, false) |
Sting | 문자열, 외따옴표나 쌍따옴표를 사용해야 한다 ex: 'value' 또는 "value" |
Number | 숫자, 따옴표를 사용하지 않는다. 때문에 '10' 는 문자열, 10은 숫자로 판별한다. |
undefined | 변수에 값이 할당되지 않으면 가지게 되는 값으로 원시 자료형이다. |
null | 값 자체가 비어있는 것을 의도적으로 표현할 때 사용 |
Object | 타 언어의 딕셔너리에 해당하는 형태, {key1: value, key2: value} 형태로 사용한다. |
Array | 배열, [value0, value1, value2] 형태로 표현한다. |
NaN | 숫자가 아닌 값을 숫자로 변환할 때 이것으로 반환된다. |
Function | 함수 |
■Object
아래 예시를 보자
const person = {
name: '사람이름',
age: 24
};
person.name;
person['name'];
person.hobby;
위에 선언된 person은 const 변수이며 Object형태로 선언되었다.
person에는 name: '사람이름' 과 age: 24가 선언되었다.
여기서 '사람이름'은 따옴표를 통해 선언되었으니 문자열로 인식하고
24는 그런거 없이 선언되었으니 숫자로 인식한다.
그 아래 person.name 을 통해 person 이라는 변수의 name에 접근할 수 있다.
마찬가지로 person.age 라고 입력하면 person의 age에 접근할 수 있다.
아래 person['name']은 person.name과 모양만 다를뿐 같은 명령이다.
person에는 hobby라는 것이 선언된 적이 없다.
때문에 person.hobby는 undifined라는 값이 반환된다.
■Array
여러개의 값을 나열한다.
const ay = [123, 222, 314, 456]
ay[0];
ay[1];
ay라는 변수에 123 과 222와 314와 456이 순서대로 선언되었다
각 칸을 인덱스라고 하며 가장 처음의 칸은 0번째 칸으로 본다
즉 ay의 0번째 칸에는 123이라는 값이, 2번째 칸에는 314라는 값이 들어가 있다.
아래 ay[0]이라고 입력하면 123이라는 값이 나올 것이다.
■NaN
Not a Number의 줄임말로 다소 특이하다.
NaN은 그 어떤 값과도 같다고 여겨지지 않는다.
isNaN() 라는 명령어는 ()안의 값이 NaN인지 아닌지를 판별해주는 명령어다.
NaN === NaN; // false
Num.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Num.NaN); // true
■Function
각종 기능을 모아둔 곳으로 자판기에 비유할 수 있다.
자판기는 동전을 받아서 3번째 단추를 누르면 음료수가 나온다고 하자
동전과 단추 번호는 parameter라고 하며
나온 음료수는 return이라고 한다.
자판기는 동전과 단추번호를 받고 어떤 음료수를 줘야할지, 또는 반응해야할지(돈이 부족하다던가, 거스름돈이라던가)
를 판단해야 하는데 그 판단과정이 바로 함수의 내용이라고 할 수 있다.
아래 예시를 보자
function getMyName() {
return '함수가 반환할 값';
}
getMyName(); // 위처럼 정의된 함수는 이렇게 사용할 수 있습니다.
// Print: '함수가 반환할 값'
getMyName이라는 함수(자판기)가 선언되었다
()안이 바로 parameter인데 여기가 비어있다는건 아무것도 받지 않는다는 뜻이다.
{}안은 함수의 내용인데 return을 빼면 아무 내용도 없다.
그러니까 묻지도 따지지도 않고 음료수(return)을 내놓는다고 보면 된다.
여기서 내놓는 음료수는 '함수가 반환할 값' 이다.
이제 이 자판기는
getMyName() 이라고 적어만 주면 작동한다.
const variable = function() {
return '함수가 반환할 값';
}
variable(); // 위처럼 정의된 함수는 이렇게 사용할 수 있습니다.
// Print: '함수가 반환할 값'
이건 변수에 함수를 할당한 것이다.
별 의미는 없는것 같다.
function getMyName(myName) {
return myName;
}
getMyName('인자를 넣습니다.'); // 위처럼 정의된 함수는 이렇게 사용할 수 있습니다.
// Print: '인자를 넣습니다.'
맨 위의 예시와는 달리 ()안에 myName이라는 내용이 들어가 있다.
이는 이 자판기가 myName이라는걸 받는다는 뜻이다.
그런데 return도 myName이다
이는 받은 값을 그대로 돌려준다고 해석할 수 있다.
몇몇 고장난 자판기는 동전을 넣는 족족 다시 동전을 토해내는데
이거랑 똑같은거라고 생각할 수 있다.
■진실 혹은 거짓
진실로 취급될 수 있는 값 | 거짓으로 취급될 수 있는 값이 아닌 모든 것 |
거짓으로 취급될 수 있는 값 | 빈문자열 '', 숫자 0, 불리언 false, null, undefied, NaN |
단, 항상 진실로 취급될 수 있는 값이 있으니 이것은 앞서 배운 Array와 Object다
컴퓨터에는 여러종류의 값이 있는데 여기에 어거지로 진실 혹은 거짓을 규명해 줄 수 있는데 이게 바로 Boolean 명령이다.
괄호안에 집행하고자 하는 대상을 넣어주면 된다.
예시
Boolean('') 는 빈 문자열이 들어가 있으니 거짓으로 판명한다.
Boolean('죄수')는 죄수라는 문자열이 들어가 있으니 진실로 판명한다.
Boolean(undefined)는 undefied가 들어가 있으니 거짓으로 판명한다.
■ 조건문
어느 언어에나 있는 흔하디 흔한 if문과 else문과 else if문이다.
if와 else if는 ()를 대동한다. ()안이 조건이며 이 내용이 참이면 실행하고 거짓이면 else를 실행한다.
대략적인 구조는 아래 예시를 보자
if (조건1) {
실행문1
} else if (조건2) {
실행문2
} else {
실행문3
}
조건 1이 참이면 실행문 1을 수행한다.
조건 1이 거짓이면 조건 2를 판명한다.
조건 2가 참이면 실행문 2를 수행한다.
조건 2가 거짓이면 실행문 3을 수행한다.
if (죄가 있는가?) {
징역!
} else if (금전적 손해를 끼쳤는가?) {
배상!
} else {
석방!
}
죄가 있으면 징역을, 손해를 끼쳤으면 배상을, 그것도 아니면 석방을 하라는 예시문이다.
대략 이런 절차로 조건문이 실행된다고 할 수 있다.
■논리연산자
논리연산자 종류: &&, ||, !
&& | AND연산으로 좌우의 값이 둘 다 true일 때 true를 내놓는다. |
|| | OR연산으로 좌우 값 중 하나라도 true일 때 true를 내놓는다. |
! | NOT연산으로 참거짓 값을 뒤집는다 |
AND와 OR은 둘 다 좌우에 비교대상을 넣어야 하지만
NOT은 그렇지 않다.
!'value' 라고 입력하면 value의 참거짓 여부가 뒤집어진다.
'value'는 빈 문자열이 아니기 때문에 기본적으로 참으로 판명한다.
그러나 앞에 !가 있으므로 !'value'는 거짓으로 판명된다.
과제는 오늘내로
문제는 천천히
■반복문
어느 언어에나 다 있는 흔하디 흔한 for문이다
원래 while도 있지만 별 차이는 없기에 생략한다.
for문은 괄호안에 3가지 구문을 넣어줘야 한다.
for (초기문 ; 조건문; 증감문){반복하고자 하는 내용}
으로 구성된다.
for (let i = 0; i < 5; i++) {
}
초기문: 우선 i를 선언하고 이것의 초기값은 0이다.
증감문: 한번 실행할 때 마다 i값을 1씩 올린다 (i++)
조건문: i < 5 라면 반복하고자 하는 내용을 실행한다.
즉 한번 실행할 때 마다 i값이 1씩 올라가고 그것이 조건문을 만족하는 이상 계속 반복한다.
■제어문
종류: break, continue
제어문은 특정 조건을 만족하면 조건문을 아예 끝내버리거나 몇 단계 건너뛰게 하는 명령이다.
break | 반복문을 아예 끝내버린다. 이게 실행되면 반복문은 끝난다. |
continue | 다음 반복스탭으로 넘어간다. |
for (let i = 0; i < 5; i++) {
if(i===2) continue;
if(i===4) break;
console.log(i);
}
맨 아래 console문은 ()안의 값을 출력하라는 뜻이다.
i가 시작할때 0이니 0을 출력한다.
i가 1이 증가하고 그 값을 출력한다.
이것을 i가 5가 될 때까지 반복한다.
위의 내용이 반복문의 내용이지만 중간에 i가 2일 경우 continue를, 4일령우 break를 하라고 하고 있다.
i가 2가 되면 console.log(i)명령을 수행하지 않고 i를 3 올린다.
그리고 i가 4가 되면 반복문이 끝난다.
때문이 위 구문을 출력하면 0 1 3 이 출력된다.
■for-of문
Array, Map과 같은 반복 가능한(Iterable) 객체의 value(요소)를 하나씩 반복한다.
const persons = ['아마', '홍길동', '김아무개'];
for (const person of persons) {
console.log(person);
}
배열이 선언되어 있고 그 안에 3개의 값이 있다.
person은 for문에서 사용하는 이름이고 persons는 배열의 이름이다 (비슷하지만 다름을 주의)
가장 처음, persons의 값의 첫번째인 아마를 받아온다.
그리고 그것을 출력한다.
그 다음, persons의 다음 값인 홍길동을 받아오고 출력한다.
이런식으로 작동하며 출력결과 값은
아마
홍길동
김아무개
가 된다.
■for-in문
위의 for-of와 비슷하지만 내용이 아닌 인덱스번호를 가져온다는게 차이점이다.
const persons = ['아마', '홍길동', '김아무개'];
for (const person in persons) {
console.log(person);
}
이를 출력하면 0 1 2 가 된다.
만약 인덱스의 내용을 출력하고 싶다면 다음 예시를 참조하자
const persons = ['아마', '홍길동', '김아무개'];
for (const index in persons) {
const person = persons[index];
console.log(person);
}
이를 출력하면 아마 홍길동 김아무개가 된다.
이렇게 person이라는 변수를 선언하고 그것을 맨 위의 persons의 index로 선언하면 된다
하지만 굳이 이렇게 쓸 필요는 없고 그냥 내용이 필요하면 for-of문을 쓰면 될듯하다
■함수
예를 들어 슈퍼마켓 사업을 한다고 가정한다면
각지의 슈퍼마켓 마다 계산대, 물품관리, 고객응대, 배달담당 등 다양한 부서가 있을 것이다.
이 부서가 함수라고 할 수 있다.
계산대를 예로 들자면 계산대 직원이 일을 하기 위해선
고객이 가져온 물품이 있어야 하고 그 물건을 바탕으로 금액을 청구하고 계산한다.
여기서 고객이 가져온 물품, 지불할 금액 등이 인자(파라미터 또는 매개변수)이고
계산 후 고객에게 주는 물품과 영수증은 리턴이라고 할 수 있다.
const sum = function(a, b) {
return a + b;
};
a와 b를 받으면 그 두개를 더한 값을 반환하는 함수이다.
가장 기본적인 형태라고 볼 수 있다.
■화살표 함수
함수의 한 형태로 함수를 짧게 작성한거라 할 수 있다.
const sum = (a, b) => a + b;
아까 위에 작성한 함수와 같은 내용이다.
여기서 => 는 대소관계를 나타내는 것이 아님을 주의
■익명 함수
쉽게 말해 함수에 이름이 없고 대신 변수에 함수를 담아 사용하는 경우이다.
이건 1회성 함수로 자주 사용하는데 한 번 쓰고 버림으로써 불필요한 메모리를 차지하는 것을 막을 수 있다.
// 일반 함수
function foo() {
console.log("bar");
}
// 익명 함수
let foo = function () {
console.log("bar");
};
그러나 이건 순서를 지켜야한다는 단점이 있다.
코드는 위에서 아래 순서대로 작동을 하는데 함수는 어느 위치에 있든지 상관없이 불러올 수 있지만
익명함수는 호출코드가 본인보다 위에 있으면 인식하지 못한다.
■구조분해 할당
배열이나 객체가 가진 값을 분해해서 개별 변수에다 담는 것을 말한다.
■배열에서 구조분해 할당
const [a, b] = [100, 200];
console.log(a); // 100 a가 100의 값을 가져가고
console.log(b); // 200 b가 200의 값을 가져간다.
//혹은 아래와 같이 표현할수있습니다.
const array = [100,200]
const [a,b] = array
console.log(a); //100 a가 100의 값을 가져가고
console.log(b); //200 b가 200의 값을 가져간다.
// a 에는 array[0] , b에는 array[1] 값이 할당 되었습니다.
array는 원래 [100, 200]이었다
그러나 [a, b]가 array에 들어옴에 따라
a값이 100, b값이 200이 되었다.
즉 array가 가지고 있던 [100, 200]은 분해되어
a가 100을 가져가고 b가 200을 가져가게 되었다.
■객체에서 구조분해 할당
이번엔 객체를 구조분해 할당을 해보자
const student = {
name: "Sparta",
age: 18,
onlineClass: "Node JS",
};
const { name, age, onlineClass } = student
console.log(name); // "Sparta"
console.log(age); // 18
console.log(onlineClass); // "Node JS"
student라는 객체에는 name, age, onlineClass가 있고 각각 Sparta, 18, Node JS 라는 값을 가진다
그리고 그것을 name, age, onlineClass로 분해했다(이름은 똑같이 설정)
지금까지는 student가 각 3가지 값을 가졌지만
이제는 분해할 때 사용했던 이름인 name, age, onlineClass라는 변수를 사용해 그 값을 가져온다.
■동기와 비공기(Sync, Async)
동기 | 먼저 실행된 코드의 결과가 나올때까지 대기 |
비동기 | 실행된 순서와 상관없이 결과가 나옴 |
동기는 집단주의, 비동기는 개인주의라고 할 수 있다.
동기는 한 번에 수용할 수 있는 사람을 다 수용한 뒤 작업에 들어간다.
그리고 그것이 끝나야지 다음 사람을 받을 수 있다.
비동기는 수용할 수 있는 양만큼 다 수용하나 먼저 일이 끝난 사람은 돌려보내고 다음 사람을 받는다.
■Blocking Model & Non-Blocking Model
■Blocking Model이란, 코드의 실행이 끝나기 전까지 실행 제어권을 다른곳에 넘기지 않아 다른 작업을 하지 못하고 대기
■Non-Blocking Model이란, 코드의 실행이 끝나지 않아도 실행 제어권을 다른곳에 넘겨서 다른 작업을 하게 하는 것
이러한 특징 덕분에 Non-Blocking은 비동기와 연관이 깊고
Blocking은 동기와 연관이 깊다.
자바스크립트는 비동기 + Non-Blocking 을 채용하여 현재 실행중인 코드의 실행이 끝나지 않아도 다음 코드를 호출한다.
function first() {
console.log('First');
}
setTimeout(first, 1000); // 1000ms(1초) 뒤에 first 함수를 실행해준다.
console.log('Middle');
console.log('Last');
// Print: Middle
// Last
// First
이 코드의 setTimeout은 1초를 기다린 다음 first 함수를 실행하라는 뜻이다.
그러나 자바스크립트는 비동기식이고 아래 console 명령은 처리하는데 1초도 걸리지 않음으로
Middle이 먼저 출력되고 그 다음 Last, 마지막으로 first가 출력된다
만약 자바스크립트가 Blocking 모델이었다면 first, Middle, Last 순서대로 출력되었을 것이다.
■Promise
자바스크립트에서 비동기 처리를 동기로 처리하게 해주는 객체유형이다.
Promise라는 이름의 생성자를 사용한다.
new Promise(executor);
// 예제
new Promise((resolve, reject) => {
// 여기에 명령문을 입력
});
■promise의 상태
프로미스의 상태는 대기(Pending), 이행(Fulfilled), 거부(Rejected) 로 나뉜다.
대기는 말 그대로 대기상태, 이행은 연산이 성공적으로 완료된 상태, 거부는 연산이 실패한 상태이다
프로미스가 만들어 질때는 집행관(executor)가 실행된다.
집행관이 resolve함수를 호출하면 Fulfulled Promise라고 한다.
■Promise.catch
쉽게 말해 에러를 잡아내는 것이다.
■비동기 함수(Async Function)
일반함수나 화살표함수와 아주 비슷하지만 두가지가 다르다.
1. 비동기 함수의 결과값은 항상 Promise 객체로 resolve가 된다
2. 비동기 함수 안에서만 await 연산자를 사용할 수 있다.
이 두가지만 빼면 일반함수나 화살표함수처럼 사용할 수 있다
// 비동기 + 일반 함수
async function 함수이름() {
// 명령문
}
// 비동기 + 익명 함수
async function() {
// 명령문
}
// 비동기 + 화살표 함수
async () => {
// 명령문
}
3가지 모두 비슷한 방법이다.
■await 연산자
await 연산자를 사용하면 promise가 fulfil 되거나 rejected 될 때까지(성공하거나 실패할 때까지)
함수의 실행을 중단하고 기다린다.
promise의 연산이 끝나야 함수에서 반환한 값을 얻을 수 있다.
await연산자는 async함수안에서만 사용할 수 있다.
async function abcdefg() {
const result = await 'Test!';
console.log(result);
}
abcdefg();
// Print: 'Test!';
abcdefg는 임의로 정한 함수 이름이다.