에러 처리
try, catch, finally
function readFile(path){
throw new Error('파일 경로를 찾을 수 없음');
return '파일 내용'; // 안나옴
}
function processFile(path){
let content;
try{ // 오류날 것 같은 구문
content = readFile(path);
}catch(err){ // 실패시
console.log(err.name);
console.log(err.message);
}finally{
console.log('성공 실패 여부와 관계없이 호출');
}
모듈
- 하나의 html의 연결 js 파일이 여러 개인 경우 사용
- app.js와 app2.js가 있으면 app.js에서 전역 변수와 함수, app2.js에서 접근 가능
- 이걸 방지하기 위해 모듈을 만든다. ⇒ 접근 불가하지만 사용자가 스스로 컨드롤 가능
<script type="module" src="app.js"></script>
<script type="module" src="app2.js"></script>
let count = 0;
export function increase(){
count++;
console.log(count);
}
//export default는 모듈에서 1개만
import { increase } from './app';
// 1 import {increase as aa} from './app';
// 2 import * as one from './app';
// one.increase()로 해야함
console.log(count);
increase();
스프레드
- 전개구문
- 순회가 가능한거는 펼칠 수 있다
- 중복된 값을 빠르고 편하게 포함시킬 수 있다
- 함수, 배열, 객체
기본 형태
function add(a,b,c){
return a + b + c;
}
const num = [1,2,3];
//1
console.log(add(num[0],num[1],num[2]));
//2
console.log(add(...num));
function k(first,second,...nums){
console.log(nums);
}
k(1,2,5,6,7,8); // [5,6,7,8]
배열을 복사할 때 concat대신 사용
const fr = ['⭐️','🌕'];
const fs = ['💥','🧮'];
// 1
console.log(fr.concat(fs));
// 2
console.log([...fr, ...fs]);
객체에도 사용
const ky = {
name: 'ky',
age: 25,
}
const newone = {
...ky,
hobby: 'football',
}
console.log(newone);
구조 분해 할당(비 구조화 할당)
- 그룹화를 하여 할당해준다
- 객체에서 키와 값의 이름을 같게하면 생략가능하다.
// 1
const resister = (id, pw) => ({ id:id, pw:pw });
console.log(resister('kky', 123));
// 2
const resister = (id, pw) => ({ id, pw });
console.log(resister('kky', 123));
- 배열은 인덱스를 기준으로 한다.
- arr[0] 이런 식으로 받아오기 싫을 때 사용
배열 구조 분해 할당
const arr = [10,20,30,40];
const [first,second, ...num] = arr;
console.log(first,second,num); 10,20,[30,40]이 나옴
const arr = [10,20];
const [first,second, third = 30] = arr;
let a = 10;
let b = 20;
[a,b] = [b,a];
console.log(a,b);
객체 구조 분해 할당
- 객체는 키 값을 통해 접근
- age: aa로 해주면 console.log(aa)로 접근 가능
let ob = {
one: 'one1',
two: 'two1',
three: 'three1',
};
let {one,two,three} = ob;
console.log(one,two,three);
Set, Map
- 객체 : 키가 있는 컬렉션을 저장
- 배열 : 순서가 있는 컬렉션을 저장
맵(Map)
- 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다.
- 키가 있는 데이터를 저장한다는 점에서 객체와 유사하다.
- 맵은 키에 다양한 자료형을 허용한다는 점에서 차이가 있다.
- 즉, key-value의 쌍을 저장하며 각 쌍의 삽입 순서도 기억하는 컬렉션이다.
- 맵은 객체와 달리 키를 문자형으로 변환하지 않는다.
- 키에 자료형 제약이 없다.
맵 주요 메서드와 프로퍼티
- new Map()
- 맵을 만든다.
- map.set(key, value)
- key를 이용해 value를 저장한다.
- map.get(key)
- ``key`에 해당하는 값을 반환한다.
- key가 존재하지 않으면 undefined를 반환
- map.has(key)
- key가 존재하면 true, 존재하지 않으면 false를 반환
- map.delete(key)
- key에 해당하는 값을 삭제
- map.clear()
- 맵 안의 모든 요소를 제거
- map.size
- 요소의 개수를 반환
셋(set)
- 중복을 허용하지 않는 값을 모아 놓은 특별한 컬렉션
- set에 키가 없는 값이 저장된다.
주요 메서드
- new Set(iterable)
- 셋을 생성
- 이터러블 객체를 전달받으면(대개 배열을 전달받음) 그 안의 값을 복사해 셋에 넣어준다
- set.add(value)
- 값을 추가하고 셋 자신을 반환
- set.delete(value)
- 값을 제거
- 호출 시점에 셋 내에 값이 있어서 제거에 성공하면 true, 아니면 false를 반환
- set.has(value)
- 셋 내에 값이 존재하면 true, 아니면 false를 반환
- set.clear()
- 셋을 비워주기
- set.size
- 셋에 몇 개의 값이 있는지 카운트
이터러블
- 반복이 가능한 객체
- 순회가 가능한 연산자 for of, spread 사용
- Array, String, Map, Set
자바스크립트에서 반복되는 열거 가능(enumerable)한 속성이 있는 객체를 '이터러블(iterable)하다'고 한다. 이터러블한 객체에는 string, array, map, set 등이 있다. 이터러블한 객체의 프로토타입 객체에는 모두 Symbol.iterator 메서드가 있다.또한 이터레이터가 배열과 다른 점은, 배열은 전체 값이 할당되어야 하지만 이터레이터는 무한대로 표현될 수 있다는 것이다.
이터레이터
1. 이터레이터란?
이터레이터는 반복을 위해 설계된 특정 인터페이스가 있는 객체이다. 두 개의 속성 {value, done}을 반환하고, next 메서드를 가진다. MDN에서는 '시퀀스를 정의하고 종료시의 반환값을 잠재적으로 정의하는 객체'라고 되어 있다. Array.prototype.values()를 사용하면 배열의 각 인덱스에 대한 값을 가지는 새로운 Array Iterator 객체를 반환하여 이터레이터를 만들 수 있다.
const book = [
'a', 'b', 'c', 'd',
];
const it = book.values();
it.next(); // {value: 'a', done: false}
it.next(); // {value: 'b', done: false}
it.next(); // {value: 'c', done: false}
it.next(); // {value: 'd', done: false}
it.next(); // {value: undefined, done: true}
it.next(); // {value: undefined, done: true}
이터레이터를 생성하면 next() 메소드를 반복적으로 호출하여 명시적으로 반복시킬 수 있다. value 프로퍼티는 다음 시퀀스의 값을 반환하고, done은 시퀀스의 마지막 값이 산출(소비)되었는지 여부를 boolean으로 반환한다. 마지막 값이 반환된 후에 next()를 호출하면 메서드는 done을 true로 리턴한다.
제너레이터
- 이터러블, 이터레이터 객체를 만드는 손 쉬운 방법
동작은 function* 문법을 사용해서 작성하며 next를 통해 실행합니다.next 메소드를 통해 실행이 되며 yield 문을 만나면 정지합니다.
function* generatorFunc() {
yield 1;
yield 2;
yield 3;
}
const it = generatorFunc();
console.log(it.next()); // { value: 1, done: false }
console.log(it.next()); // { value: 2, done: false }
console.log(it.next()); // { value: 3, done: false }
console.log(it.next()); // { value: undefined, done: true }
스코프
- 블럭 안의 변수는 블럭 안에서만 유효 ⇒ 지역 변수
- 블럭 외부에서는 내부의 변수를 참조하지 못함
- 블록 외부 변수는 내부에 사용 가능
- 가장 근접한 외부 변수를 참조함
const text = 'hello'; { const text = 'hi'; { console.log(text); // hi } } function name(){ let dog = '재롱'; } console.log(dog) // err!!
- 이름 충돌 방지, 메모리 절약
- 코드 블럭을 사용하는 모든 곳
- if, for, function, object
{const a = 10}
console.log(a) // err!
가비지 컬렉션
- 쓰레기 수집
- 메모리가 없을 때 사용
- 자바스크립트 엔진 백그라운드 프로세스 (자동으로 해줌)
- 글로벌 변수는 앱이 종료될 때까지 계속 메모리에 유지
- 블럭 내부 변수는 블럭이 끝나면 가비지 컬렉션에 의해 자동 소멸
호이스팅
- 자바스크립트 엔진이 코드를 실행하기 전, 변수, 함수, 클래스의 선언문을 끌어올리는 것
- 변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮김
- 함수의 선언문 전에 호출이 가능하게 해줌 (선언 이전에 호출이 가능함)
- 변수와 클래스는 선언만 호이스팅되고, 초기화는 안되었으므로 컴파일 에러 발생
- 여기서 선언은 let a
- 초기화는 let a = 10;
print();
function print(){
console.log('hi');
}
console.log(hi); // error
let hi = '안녕';
var
- 일반 코딩 방식과 다름
- 가독성과 유지보수가 안좋음
// 변수를 선언하는 키워드 없이 선언과 할당이 가능하다 그래서 선언인지, 재할당인지 구분하기 어렵다
some = 'a';
console.log(some);
// 재선언이 가능해서 변수의 이름 중복
var poo = 'gg';
var poo = 'hh';
//스코프 에러 (함수는 에러안남)
var apple = '사과';
{
var apple = '초록 사과';
}
console.log(apple) -> 초록 사과가 나옴
엄격 모드
- 자바스크립트 코드 제일 상단에 ‘use strict’;
- let, const로 선언을 해주어야하고 불완전한 자바스크립트를 업격하게 해줌
- 리액트 같은 프레임워크는 자동으로 적용, 바닐라 자바스크립트를 쓸 때는 적용해주어야함
프로토타입 prototype → 잘 안쓰임 (class가 쓰임)
- 원형
- 자바스크립트에서 객체지향을 위해서 사용함 (최신 자바스크립트와 타입스크립트는 class기반이다.)
- 프로토타입에 추가하면 생성 인스턴스들이 사용가능 부모에만 저장 자식들은 가져다씀
- 요즘 노드 백엔드 같은 경우도 ts를 사용해서 만든다.
- 모든 객체들은 내부의 숨겨진 프로토타입을 가지고 있다
- 외부에서 직접 접근이 불가
function Fruits(name,color){
this.name = name;
this.color = color;
}
const apple = new Fruits('apple','red');
Fruits.prototype.taste = function() {console.log(`${this.name} is good`)};
Fruits.prototype.size = 'small';
console.log(apple);
console.log(apple.size);
apple.taste();
const dog = {name: 'ky',age:25}
console.log(Object.keys(dog)); // Object.prototype.keys()
console.log(Object.values(dog));
console.log(Object.entries(dog));
const arr = [1,2,3]; // const arr = new Array(1,2,3);
arr.sort(); // 이것은 Array.prototype.sort();임
클로저
함수가 속한 렉시컬 스코프(Lexical Environment)를 기억하여, 함수가 렉시컬 스코프 밖에서 실행될 때도 이 스코프에 접근할 수 있게 해주는 기능
function sayHello () {
const a = 'Hello';
const b = 'World';
function sumString () {
console.log(a + ' ' + b);
}
return sumString;
}
const myFunc = sayHello();
myFunc(); // 'Hello World'
예제를 살펴보면, myFunc라는 변수는 sayHello 함수를 호출하고 있습니다. 그래서 myFunc를 실행하게 되면 어떠한 문제 없이 Hello World가 잘 출력됩니다. 여기서 살펴볼 점은 myFunc의 부분은 변수 a와 b가 담겨 있는 sayHello 함수 스코프의 바깥에 있는데도 불구하고 a와 b를 합친 Hello World를 잘 출력한다는 것입니다.
그 이유가 바로 클로저(Closure) 때문입니다. 모든 자바스크립트 함수는 선언(생성)될 당시에 클로저가 형성되어 주변 환경, 즉 렉시컬 스코프를 기억할 수 있게 되는 것
This에 대해
- 인스턴스 자기 자신을 가리키는 것
- c++, c#, java 코드 상에서 this 바인딩 정적으로 결정
- js,ts 런타임 상에서 this 바인딩 동적으로 결정
/*
* 글로벌 this
* 브라우저:window
* 노드: 모듈
*/
/*
* 함수 내부 this
* 엄격 모드: undefined
* 느슨한 모드: globalThis
*/
/*
* 생성자 함수 또는 클래스에서의 this
* 앞으로 생성될 인스턴스 자체를 가리킴
*/
동적 바인딩 TS, JS
- 호출하는 caller에 따라 동적으로 결정
- this가 한 번 결정이 되는게 아니라 계속 바뀜
// 동적 바인딩을 수동으로 정적 바인딩으로 바꾸기
this.name = this.name.bind(this);
// 화살표 함수 사용하면 함수 밖에서 제일 근접한 스코프의 this를 가리킴
print() => console.log(`${this.name}`);
정적 바인딩 Java, C#, C++
- 자바, C#, C++ 같은 대부분의 객체지향 언어의 this는 항상 자신의 인스턴스 자체를 가리킴
- 정적으로 인스턴스가 만들어지는 시점에 this가 결정, 변경불가
바벨이란?
- 바닐라 자바스크립트 버전을 되돌아 갈 때 사용
'Backend > JS & TS' 카테고리의 다른 글
타입스크립트 - part 1 (1) | 2023.03.23 |
---|---|
자바스크립트 - part 4 (0) | 2023.03.23 |
자바스크립트 - part 2 (0) | 2023.03.23 |
자바스크립트 - part 1 (0) | 2023.03.23 |
댓글