모던 자바스크립트 이해하기
모던 자바스크립트란?
자바스크립트의 표준
현시점에 사용하기 적합한 범위 내에서 최신 버전의 자바스크립트
자바스크립트 기본 개념 더 견고히
const → 재할당이 불가능하다
x → 재할당이 가능하다.
const → 상수를 만드는 용도
어떨 때는 변수이고 어떨 때는 상수이다.
자바스크립트 동작 원리
데이터 타입의 특징과 종류
기본형 → Number, String, Boolean, Null, Undefined
Symbol → 유일한 값을 만들 때
BigInt → 엄청 큰 숫자를 다룰 때.
참조형 → Object
typeof 연산자 → 데이터 타입의 확인
typeof 'Codeit' → String
typeof null → Object
곱셈의 경우 대상을 모두 숫자형으로 변환한다!
불린인 듯 불린 아닌 불린 같은 값
if문에 조건식을 원래 넣는데, 문자열을 넣으면 어떻게 되냐..?
문자열 → True처럼 평가된다.
불린 타입의 값이 필요한 경우에는 불린으로 형 변환 된다.
True →나머지 값들(빈 배열과 빈 객체는 트루 값이다) ⇒ Truthy
False →false, null, undefined, NaN, 0 ⇒ Falsy
AND와 OR의 연산 방식
논리 연산자는 양쪽 값들 중 어느 한쪽을 선택하는 방식으로 동작한다.
AND: 왼쪽이 True이면 오른 쪽 값을 return하고 왼쪽이 false이면 왼쪽 값을 return한다.
OR: 왼쪽이 True이면 왼쪽 값을 , 왼쪽이 false이면 오른쪽 값을 return
함수 호출할 때 아무 값이 없을 경우에 예외 처리를 할 때 사용할 수 있다.
AND연산자가 OR연산자보다 우선순위가 높다.
null 병합자
null ?? 'codeit' →'codeit'
??왼편의 값이 null이나 undefined라면 오른쪽 값이 리턴
왼편의 값이 null이나 undefined가 아니라면 왼쪽 값이 리턴
변수와 스코프
var → 선언이 분명히 나중에 되었지만, 마치 선언이 위로 올라간듯한 현상: Hoisting, 선언 부분만 끌어올라가기 때문에 값은 끌어올려지지 않는다.
let이나 const키워드는 변수 이전에 접근할 수가 없다. 오류 파악하기가 쉽다.
중복 선언의 차이가 있다.
var키워드는 중복 선언이 가능하다.
var title = '!!!' var title = '123'
이래버리면 값이 바뀐다.
let이나 const 키워드는 중복 선언이 불가능하다.
즉, 같은 이름으로 변수 선언이 안 된다.
스코프의 차이가 있다.
var → 함수 단위로만 스코프가 설정된다. 조건문이나 반복문에서 새로운 변수를 만들더라도 전부다 전역변수로 평가된다.
let → 중괄호가 사용되는 걸 기준으로 변수의 유효범위를 구분한다. 함수를 떠나서 그냥 코드 블럭을 기준으로 스코프를 잡는다.
함수를 만드는 방법
function 함수이름 (파라미터){
동작
return 리턴 값
}
⇒ 이 방식은 함수 선언
바로 함수 선언을 변수에 할당하는 거다.
const printCodeit = function(){
}
printCodeit(); ⇒ 함수 표현식이라 한다. ⇒ 함수 선언을 값처럼 사용하는 것이 포인트다
함수 선언의 경우 호이스팅이 일어난다. 선언문이 위쪽으로 끌어올려짐
변수를 할당해서 함수를 만드는 함수 표현식은 선언 이전에 함수를 실행할 수 없다.
스코프의 차이
함수 선언 → 변수의 var키워드 처럼 함수 스코프를 가짐.
함수 안에 선언된 함수는 함수 밖에서 호출 할 수 없지만, 함수가 아닌 다른 코드 블록에서 함수 선언을 하면 전역적으로 호출이 가능함
함수 선언식 → 할당된 변수에 따라 스코프가 달라질 것이다.
이름이 있는 함수 표현식
함수 표현식으로 함수가 할당된 변수는 자동으로 name이라는 프로퍼티를 가지게 된다.
이름이 없는 함수를 변수에 할당할 때는 변수 이름 그 자체를 문자열로 가진다.
하지만 일므을 붙여주게 되면 name은 함수 이름을 문자열로 갖게 된다.
이 이름은 함수 내부에서 함수 자체를 가리킬 때 사용되고, 함수를 외부에서 호출할 때 사용할 순 없다.
즉시 실행 함수
즉시 실행 함수는 말 그대로 선언과 동시에 실행이 이뤄지기 때문에 일반적으로 프로그램 초기화 기능에 많이 활용됩니다.
(function init() {
// 프로그램이 실행 될 때 기본적으로 동작할 코드들..
})();
Plain Text
복사
혹은 재사용이 필요 없는, 일회성 동작을 구성할 때 활용하기도 하는데요.
const firstName = Young;
const lastName = Kang;
const greetingMessage = (function () {
const fullName = `${firstName} ${lastName} `;
return `Hi! My name is ${fullName}`;
})();
Plain Text
복사
이렇게 함수의 리턴값을 바로 변수에 할당하고 싶을 때 활용할 수 있습니다.
그리고, 전역변수와 지역변수의 개념 알고 계시죠?
즉시 실행 함수에서 사용하는 변수들은 함수 내에서만 유효하기 때문에 이런 점을 활용하면, 일시적으로 사용할 변수의 이름들을 조금 자유롭게 작성할 수도 있다는 점. 잘 기억해 두세요! :)
값으로서 함수
const printJS = function(){
console.log('JavaScript');
}
console.dir(0)
console.dir(printJS) ⇒ 객체이다.
자바스크립트의 함수가 객체 타입으로 평가된다.
어디에서나 할당될 수 있고, 다양한 형태로 호출 가능하다
함수 표현식으로 함수를 선언하고 호출할 수도 있고
1.
객체 안에 프로퍼티로 함수를 선언하고 프로퍼티에 접근해서 함수를 호출할 수도 있다.
2.
배열에 담아서 함수를 호출할 수도 있다.
3.
값으로 전달하기 때문에, 함수를 파라미터로 전달할 수도 있다.
a.
다른 함수의 파라미터로 전달된 함수를 콜백함수라고 한다.
4.
리턴으로 함수를 리턴할 수도 있다. ⇒ 고차함수라고도 한다.
a.
이중함수를 사용해서 고차함수를 바로 호출할 수도 있다.
Parameter
함수를 호출할 때, 바깥에서 안쪽으로 값을 전달받고 싶을 때 → 파라미터
파라미터로 전달하는 값 = Argument , 함수를 선언할 때 받는 변수 → 파라미터
파라미터의 기본값: 아무것도 전달하지 않는다면? → Undefined라고 뜨는데
default값을 설정할 수 있다. 옵셔널 파라미터처럼
파라미터가 Undefined일 때도 기본값이 동작된다.
Arguments
파라미터보다 많은 갯수의 Argument를 전달되면, 갯수보다 많은 parameter는 잘린다.
함수 내부에서는 arguments라는 객체가 있다.
arguments 객체는 배열과 비슷한 모양이지만, 유사배열이다.
console.log(arguments.length);
console.log(arguments[0]);
for(const arg of arguments){
console.log(arg);
} ⇒ argument갯수에 따라 유연하게 함수를 작성할 수 있다.
Rest Parameter
1.
유사 배열이라서 배열의 메소드를 다룰 수가 없다
2.
특정 몇 개만 뽑아내려면 인덱싱을 통해 다뤄야한다.
function printArguments(...args){
for(const arg of args){
console.log(arg);
}
console.log('————-');
};
function printRank(first, second, ...others){
console.log('코드잇 레이스 최종 결과');
console.log('우승: ${first}');
console.log('준우승: ${seconde}');
for( const arg of others){
console.log('참가자: $(arg)');
}
}
Rest Parameter ⇒ 파라미터로 정해져있는것들 외에 나머지 argument를 배열로 저장. 배열의 메소드를 사용할 수 있다.
Arrow Function
기존의 함수 선언 방식을 보다 간결하게 만들어주는 문법이다.
모든 Arrow Function은 익명 함수이다.
1.
파라미터가 하나인 애들은 파라미터를 감싸는 소괄호를 없앨 수 있다.
파라미터가 두개 있거나 없으면 소괄호를 없애면 안 된다.
2.
동작이 return문 하나로 이뤄지면 중괄호도 없앨 수 있다.
const getTwice = (number) => {
return number *2;
}
const getTwice = number => number *2;
myBtn.addEventListener('click',() =>{console.log('button is called');});
JavaScript
복사
3. return값이 객체인 경우에, 중괄호와 return 기호를 없애버리면 에러가 난다.
this
console.log(this) ⇒ window객체가 출력됨
함수 내부에서 주로 사용된다. 객체의 메소드를 만들 때 중요한 역할을 한다.
this ⇒ 함수를 호출한 객체를 가리키는 키워드이다.
어떤 객체가 함수를 호출했느냐에 따라 상대적으로 값이 변할 수 있다.
Arrow Function → this 값은 변하지 않는다. Arrow function이 선언되기 직전에, this 값과 똑같이 움직인다.
자바스크립트의 문법과 표현
문장과 표현식
표현식 → 어떤 값으로 수렴하거나 return하는 것
문장 → 말 그대로 문장
따라서 범위상 표현식 < 문장
표현식이 아닌 문장 ⇒ if문, for문 등등
조건을 다루는 표현식
if(조건){
}else{
}
조건 연산자 -> 삼항연산자
조건 ? truthy할 때 표현식 : falsy할 때 표현식
return score > CUT_OFF? '합격!': '불합격!';
const msg = x > 3 ? 'x는 3보다 크다.' : 'x는 3보다 크지 않다.';
조건에 따른 결과 값을 msg에 넣는 것
JavaScript
복사
Spread 구문
여러개의 배열을 개별적인 요소로 펼치는 것
const numbers = [1,2,3];
console.log(...numbers); -> 1,2,3
=> Rest Parameter랑 문법이 비슷하다.
근데 동작하는 방식이 다르니까 착각하지 말자!
객체 타입은 참조형으로 전달된다.
이 때 배열을 복사할 때 spread구문을 사용하며 복사가 가능하다.
const interacttiveWeb = [...webPublishing, 'Javascript'];
여러개의 parameter가 있는 함수에 스프레드 구문을 활용하여 펼쳐서 전달할 수 있다.
스프레드를 펼쳐서 객체로 만들면 index -> property 가 된다.
const newObject = {... members };
JavaScript
복사
객체 Spread하기
아래 코드를 살펴봅시다.
const codeit = {
name: 'codeit',
};
const codeitClone = {
...codeit,// spread 문법!
};
console.log(codeit);// {name: "codeit"}console.log(codeitClone);// {name: "codeit"}
Plain Text
복사
이렇게 중괄호 안에서 객체를 spread 하게되면, 해당 객체의 프로퍼티들이 펼쳐지면서 객체를 복사할 수가 있게 됩니다.
const latte = {
esspresso: '30ml',
milk: '150ml'
};
const cafeMocha = {
...latte,
chocolate: '20ml',
}
console.log(latte);// {esspresso: "30ml", milk: "150ml"}console.log(cafeMocha);// {esspresso: "30ml", milk: "150ml", chocolate: "20ml"}
Plain Text
복사
이런 식으로 다른 객체가 가진 프로퍼티에 다른 프로퍼티를 추가해서 새로운 객체를 만들 때 활용할 수도 있겠죠?
주의 사항
Spread 구문을 사용해서 새로운 배열을 만든다거나 함수의 아규먼트로 사용할 수는 없습니다.
const latte = {
esspresso: '30ml',
milk: '150ml'
};
const cafeMocha = {
...latte,
chocolate: '20ml',
}
[...latte];// Error
(function (...args) {
for (const arg of args) {
console.log(arg);
}
})(...cafeMocha);// Error
Plain Text
복사
그렇기 때문에 객체를 spread할 때는 반드시 객체를 표현하는 중괄호 안에서 활용해야 한다는 점. 잘 기억해 두시면 좋을 것 같습니다! :)
모던 프로퍼티 표기법
const title = 'Codeit';
const birth = 2017;
const job = '프로그래밍 강사';
const user = {
title: title,
birth: birth,
job : job
}
변수에 할당된 값을 활용해서 프로퍼티를 만들 수 있다.
활용할 변수의 이름과 프로퍼티 네임이 같다면 하나만 작성하는 표현이 가능하다.]
const title = 'Codeit';
const birth = 2017;
const job = '프로그래밍 강사';
const user = {
title
birth
job
}
변수 뿐만 아니라 함수 또한 메소드로 할 때 축약형 표기가 가능하다.
객체 내부에서 메소드를 선언할 때도 활용할 수 있다.
const user = {
getFullName: function(){
return '${this.firstName} ${this.lastName}';
}
}
콜론과 function을 생략할 수 있다.
const user = {
getFullName(){
return '${this.firstName} ${this.lastName}';
}
}
계산된 속성명(computed property name)
대괄호로 감싸서 속성을 작성할 수 있다.
변수에 감싸면 함수의 리턴값이나 변수의 이름을 속성이름으로 사용할 수 있다.
const user = {
['Code'+'it']: 'value';
}
console.log(user)
JavaScript
복사
옵셔널 체이닝
nction printCatName(user) {
console.log(user.cat?.name);
}
JavaScript
복사
위 코드에서 볼 수 있는 것처럼 물음표와 마침표를 붙여 사용하는 부분이 바로 옵셔널 체이닝 연산자(?.)인데요.
만약 옵셔널 체이닝 연산자 왼편의 프로퍼티 값이 undefined 또는 null이 아니라면 그다음 프로퍼티 값을 리턴하고 그렇지 않은 경우에는 undefined를 반환하는 문법입니다.
옵셔널 체이닝 연산자의 동작 원리를 삼항 연산자를 통해 구체적으로 표현하면 다음과 같이 작성할 수 있는데요.
function printCatName(user) {
console.log((user.cat === null || user.cat === undefined) ? undefined : user.cat.name);
}
JavaScript
복사
이렇게 보니 옵셔널 체이닝 연산자가 어떻게 동작하는지 이해가 되죠?
이전에 배운 null 병합 연산자와 함께 활용하면 다음과 같이 응용할 수도 있습니다.
function printCatName(user) {
console.log(user.cat?.name ?? '함께 지내는 고양이가 없습니다.');
}
const user2 = {
name: 'Young',
}
printCatName(user2);// 함께 지내는 고양이가 없습니다.
JavaScript
복사
이후 레슨에서 자세히 다루겠지만 자바스크립트에서 에러를 방지하는 일은 굉장히 중요한데요.
중첩된 객체를 다룰 때 에러를 방지하기 위해 다양한 방식을 활용할 수 있지만 옵셔널 체이닝 연산자를 활용하면 훨씬 더 간결하게 코드를 작성할 수 있다는 점! 잘 기억해 두세요! :)
Destructuring(구조 분해)
배열이나 객체의 구조를 분해하는 문법
배열 → 인덱스
객체 → 프로퍼티로 이름을 붙인다.
<배열 구조분해>
const [macbook. ipad, airpods, coupon] = rank;
rank 배열에 있는 요소들을 각 변수에 집어넣는 것
할당 연산자의 오른쪽이 배열의 형식이 아니거나 아예 아무거도 할당하지 않으면 오류가 난다.
선언된 길이의 변수와 배열의 길이가 같을 필요는 없다.
인덱스에 따라 순서대로 변수에 할당된다. 변수가 부족하면 그냥 배열 요소가 할당이 안된다.
가장 마지막 변수에 마침표 세개를 붙이면, 남은 요소를 마지막 변수에 배열로 할당한다.
const[macbook, ipad, airpods, ...coupon] = rank;
할당하는 배열의 길이가 변수 개수 길이보다 작으면 남은 변수에는 undefined가 할당된다.
기본값을 할당할 수 있다.
const [macbook,. ipad, airpods, coupon = "기본"];
변수 값을 swap할 때 쓰인다.
[macbook, ipad ] = [ipad, macbook];
JavaScript
복사
<객체의 구조분해>
const {title,price} = macbook;
객체에서 변수의 이름과 똑같은 property name이 있으면 그 값을 집어넣는다.
객체에 존재하지 않는 프로퍼티 네임으로 변수가 되어있으면, undefined가 뜨고, 기본값을 지정할 수도 있다.
const{ title, ...rest} = macbook;
해당하는 프로퍼티 네임에 값을 넣은 다음에, 나머지 프로퍼티 네임들을 모아서 객체로 넣는다.
const[title: product, ...rest} = macbook;
이러면 title이라는 프로퍼티가 product라는 변수에 집어넣는다.
JavaScript
복사
<함수와 구조분해>
//배열//
function getArray(){
return ['컴퓨터','냉장고','세탁기']
}
const [el1,el2,el3] = getArray();
함수의 리턴값이 배열일 때 destructuring할 수 있다.
rest파라미터가 배열이라는 점을 가지고, destructuring을 할 수 있다.
애초에 파라미터 부분에서 destructuring문법을 바로 활용할 수도 있다.
//객체//
파라미터를 객체의 형태로 작성한 경우
함수에서 프로퍼티들을 접근할 때,
destructuring문법을 사용해서 간결하게 사용할 수 있다.
파라미터 부분에서 바로 destructuring 문법을 사용할 수 있다.
DOM 이벤트를 다룰 때 다루기 쉽다.
이벤트 핸드러를 다룰 때, 이벤트 핸들러의 타겟 프로퍼티로 destructuring
JavaScript
복사
에러와 에러 객체
console.log('시작!');
const title = '코드잇';
console.log(title);
console.log('끝!');
JavaScript
복사
에러가 발생하면 그 순간 프로그램이 멈춘다.
자바스크립트로 안정적인 프로그램을 만들기 위해서는 에러를 다뤄야한다.
에러에 대한 정보가 담긴 에러 객체를 생성
에러 객체 → name, message
세 가지 정도로 요약 가능
1.존재하지 않는 변수나 함수 → 레퍼런스 에러
2. 잘못된 방식으로 데이터를 다룬다 → 타입 에러
3. 문법에 맞지 않는 에러 → syntax 에러 ⇒ 실행하기도 전에 에러 발생
의도적으로 에러 객체를 만들어낼 수 있다.
const error = new TypeError('타입 에러가 발생했습니다.')
name : TypeError, message: '타입 에러가 발생했습니다.'
에러 객체를 만든 것이지 발생시킨 건 아니다.
throw error; ⇒ 생성한 에러를 발생시킨다.
try catch 문
try{
동작시킬 구문
}catch(error){
에러 발생시 동작할 코드
}
try블럭 내에서 에러 발생 이후에는 코드가 실행되지 않는다.
catch()문 내의 파라미터로 에러 객체가 전달된다.
console.error(e) ⇒ 실제 에러처럼 출력할 수 있다.
Try catch 문 활용하기
Try Catch문 또한 코드 블록이기 때문에, const, let과 같이 코드 블럭 기준으로 다뤄지는 변수들의 사용에 주의해야한다.
Finally
try문에서 에러가 발생하지 않는다면 try문의 코드가 모두 실행된 다음에,
try문에서 에러가 발생한다면 catch문의 코드가 모두 실행된 다음 실행할 코드를 finally문에 작성하면 됩니
다시 말해 try문에서 어떤 코드를 실행할 때 에러 여부와 상관 없이 항상 실행할 코드를 작성하는 것이
finally문에서의 에러 처리는?
참고로 finally문에서 에러가 발생할 경우에는 다시 그 위에 있는 catch문으로 넘어가진 않습니다.
만약 finally문에서도 에러 처리가 필요한 경우에는 아래 처럼 try catch문을 중첩해서 활용하는 방법이 있는데요.
이런 부분도 잘 참고해 두셨다가 필요한 상황에 맞게 응용해 보세요!
유용한 내부 기능
배열 메소드 for each, map
const members = {}
members.forEach(function(member){
console.log('${member}님이 입장하셨습니다.')
});
객체.forEach(함수,인덱스,반복중인 배열);
배열의 경우에는 변수에 담지 않은 배열에 접근해서 쓰고 싶을 때 주로 쓴다.
map
객체.map(함수,인덱스,반복중인 배열);
콜백 함수 내에서 리턴 값을 작성해주게 되면 결과값을 담은 새로운 배열을 리턴한다.
단순히 배열의 반복 작업 -> forEach
반복 작업을 통해서 새로운 배열이 필요하면 -> map
최대 반복 횟수: 콜백 함수 내부에서 반복 중인 배열을 편집할 수 있다.
반복횟수는 초기의 반복 대상의 길이이다.
다만 요소를 제거하는 경우에는 반복 횟수도 줄어든다.
JavaScript
복사
filter와 find
const apples = devices.filter((el) ==> el.brand === 'Apple');
어떤 조건에 대해 필터링된 새로운 배열을 얻고 싶을 때
const myLaptop = devices.find((el) => el.name == "Gram");
리턴 값이 값이다.
find의 경우에는 조건을 만족하는 하나의 경우만 찾아서, 찾고나면 바로 종료된다.
존재하지 않는 값을 find로 찾으려고 하면 undefined 값이 도출된다.
JavaScript
복사
some과 every 메소드
some: 조건을 만족하는 요소가 1개 이상 있는지
every: 모든 요소가 조건을 만족하는지
const someReturn = numbers.some((el) => el>5);
const everyReturn = numbers.every((el) => el>5);
const someReturn = numbers.some((el,i)=> {
console.log('some:',i);
return el > 5;
});
some => 만족하는 요소가 하나라도 있는 순간 true를 리턴하고 반복을 종료
every => 조건을 만족하지 않는 요소가 찾아지는 순간 false를 리턴하고 반복을 종료
빈 배열인 경우 some -> false, every -> true이다.
JavaScript
복사
reduce 메소드
const numbers = [1,2,3,4];
numbers.reduce((acc,el,i,arr) => {
return nextAccValue;},initialAccValue);
acc => Accumulator
처음 함수의 콜백 함수의 리턴 값을 그 다음 콜백 함수의 acc에 전달한다.
initialAccValue => 첫번째 콜백 함수가 동작할 때 acc값
두번째 argument => 선택사항
생략하면 배열의 0번 인덱스에 있는 값이 첫번째 acc로 전달된다.
근데 이럴 경우에 동작하기로는 1번째 배열부터 시작된다.
JavaScript
복사
sort 메소드
배열에서 sort라는 메소드를 활용하면 배열을 정렬할 수 있습니다.
sort 메소드에 아무런 아규먼트도 전달하지 않을 때는 기본적으로 유니코드에 정의된 문자열 순서에 따라 정렬됩니다.
const letters = ['D', 'C', 'E', 'B', 'A'];
const numbers = [1, 10, 4, 21, 36000];
letters.sort();
numbers.sort();
console.log(letters);// (5) ["A", "B", "C", "D", "E"]console.log(numbers);// (5) [1, 10, 21, 36000, 4]
Plain Text
복사
그렇기 때문에 numbers에 sort 메소드를 사용한 것 처럼, 숫자를 정렬할 때는 우리가 상식적으로 이해하는 오름차순이나 내림차순 정렬이 되지 않습니다.
그럴 땐 sort 메소드에 다음과 같은 콜백함수를 아규먼트로 작성해주면 되는데요.
const numbers = [1, 10, 4, 21, 36000];
// 오름차순 정렬
numbers.sort((a, b) => a - b);
console.log(numbers);// (5) [1, 4, 10, 21, 36000]// 내림차순 정렬
numbers.sort((a, b) => b - a);
console.log(numbers);// (5) [36000, 21, 10, 4, 1]
Plain Text
복사
sort 메소드를 사용할 때 한 가지 주의해야될 부분은 메소드를 실행하는 원본 배열의 요소들을 정렬한다는 점입니다.
그래서 한 번 정렬하고 나면 정렬하기 전의 순서로 다시 되돌릴 수 없으니, 그런 경우에는 미리 다른 변수에 복사해두는 것이 좋겠죠!?
reverse 메소드
reverse 메소드는 말 그대로 배열의 순서를 뒤집어 주는 메소드 입니다.
reverse 메소드는 별도의 파라미터가 존재하지 않기 때문에 단순이 메소드를 호출해주기만 하면 배열의 순서가 뒤집히는데요.
sort 메소드와 마찬가지로 원본 배열의 요소들을 뒤집어 버린다는 점은 꼭 주의헤야 합니다.
const letters = ['a', 'c', 'b'];
const numbers = [421, 721, 353];
letters.reverse();
numbers.reverse();
console.log(letters);// (3) ["b", "c", "a"]console.log(numbers);// (3) [353, 721, 421]
Plain Text
복사
Set
Set은 여러 개의 값을 순서대로 저장한다는 점에서 배열과 비슷합니다.
하지만, 배열의 메소드는 활용할 수 없고 Map과 비슷하게 Set만의 메소드를 통해서 값을 다루는 특징이 있는데요.
Map과 마찬가지로 new 키워드로 Set을 만들 수 있고 아래와 같은 메소드를 통해 Set 안의 여러 값들을 다룰 수 있습니다.
•
set.add(value): 값을 추가하는 메소드. (메소드를 호출한 자리에는 추가된 값을 가진 Set 자신을 반환.)
•
set.has(value): Set 안에 값이 존재하면 true, 아니면 false를 반환하는 메소드.
•
set.delete(value): 값을 제거하는 메소드. (메소드를 호출한 자리에는 셋 내에 값이 있어서 제거에 성공하면 true, 아니면 false를 반환.)
•
set.clear(): Set 안의 모든 요소를 제거하는 메소드.
•
set.size: 요소의 개수를 반환하는 프로퍼티. (메소드가 아닌 점 주의! 배열의 length 프로퍼티와 같은 역할)
// Set 생성const members = new Set();
// add 메소드
members.add('영훈');// Set(1) {"영훈"}
members.add('윤수');// Set(2) {"영훈", "윤수"}
members.add('동욱');// Set(3) {"영훈", "윤수", "동욱"}
members.add('태호');// Set(4) {"영훈", "윤수", "동욱", "태호"}// has 메소드console.log(members.has('동욱'));// trueconsole.log(members.has('현승'));// false// size 프로퍼티console.log(members.size);// 4// delete 메소드
members.delete('종훈');// falseconsole.log(members.size);// 4
members.delete('태호');// trueconsole.log(members.size);// 3// clear 메소드
members.clear();
console.log(members.size);// 0
Plain Text
복사
한가지 특이한 점은 일반 객체는 프로퍼티 네임으로, Map은 get메소드로, 그리고 배열은 index를 통해서 개별 값에 접근할 수 있었는데요.
한 가지 특이한 점은 Set에는 개별 값에 바로 접근하는 방법이 없다는 점입니다.
// Set 생성const members = new Set();
// add 메소드
members.add('영훈');// Set(1) {"영훈"}
members.add('윤수');// Set(2) {"영훈", "윤수"}
members.add('동욱');// Set(3) {"영훈", "윤수", "동욱"}
members.add('태호');// Set(4) {"영훈", "윤수", "동욱", "태호"}for (const member of members) {
console.log(member);// 영훈, 윤수, 동욱, 태호가 순서대로 한 줄 씩 콘솔에 출력됨.
}
Plain Text
복사
그래서 위 코드와 같이 반복문을 통해서 전체요소를 한꺼번에 다룰 때 반복되는 그 순간에 개별적으로 접근할 수가 있습니다.
그런데, 이런 특징을 가지고도 Set이 유용하게 사용되는 경우가 있는데요.
바로, 중복을 허용하지 않는 값들을 모을 때입니다.
Set은 중복되는 값을 허용하지 않는 독특한 특징이 있는데요.
// Set 생성const members = new Set();
// add 메소드
members.add('영훈');// Set(1) {"영훈"}
members.add('윤수');// Set(2) {"영훈", "윤수"}
members.add('영훈');// Set(2) {"영훈", "윤수"}
members.add('영훈');// Set(2) {"영훈", "윤수"}
members.add('동욱');// Set(3) {"영훈", "윤수", "동욱"}
members.add('동욱');// Set(3) {"영훈", "윤수", "동욱"}
members.add('동욱');// Set(3) {"영훈", "윤수", "동욱"}
members.add('태호');// Set(4) {"영훈", "윤수", "동욱", "태호"}
members.add('동욱');// Set(4) {"영훈", "윤수", "동욱", "태호"}
members.add('태호');// Set(4) {"영훈", "윤수", "동욱", "태호"}
members.add('태호');// Set(4) {"영훈", "윤수", "동욱", "태호"}
Plain Text
복사
최초에 추가된 순서를 유지하면서, 나중에 중복된 값을 추가하려고 하면 그 값은 무시하는 특징이 있습니다.
처음 Set을 생성할 때 아규먼트로 배열을 전달할 수도 있는데요.
이런 특징을 활용해서 배열 내에서 중복을 제거한 값들의 묶음을 만들 때 Set을 활용하기도 합니다.
const numbers = [1, 3, 4, 3, 3, 3, 2, 1, 1, 1, 5, 5, 3, 2, 1, 4];
const uniqNumbers = new Set(numbers);
console.log(uniqNumbers);// Set(5) {1, 3, 4, 2, 5}
Plain Text
복사
자바스크립트 모듈
모듈이란?
파일을 여러 개의 기능으로 나누어서 파일로 만드는 기능
모듈화 → 코드를 효율적으로 관리할 수 있다. 다른 프로그램에서 재사용할 수 있다.
모듈 파일의 조건
모듈 파일이 가지는 독립적인 스코프 → 모듈 스코프
모듈 내부에서 선언한 변수나 함수는 이 파일 내에서만 사용 가능하다.
script태그로 js파일을 불러온다.
이렇게 되면, 두 파일에 나눠진 코드가 한 파일에 존재하는 것처럼 잘 실행된다.
각각의 파일이 다른 파일과 스코프를 공유할 수 없도록 해야한다.
<script type = "module" src = "printer.js"></script>
Live Server 설치하기
브라우저에서 파일을 불러오는게 아니라, 서버를 통해 html파일을 실행해야한다.
vscode의 확장기능을 사용해서 문제를 해결한다.
Extension → Live Server
서버를 통해 실행된 html파일이 열린다.
모듈 문법
특별한 모듈 문법을 통해서, 다른 파일에서 변수나 함수를 사용할 수 있게끔 한다.
export const title = 'CodeitPrinter';
export function print(value){
console.log(value);
}
import {title, print} from './printer.js';
print(title);
JavaScript
복사
html 파일에는 자바스크립트 파일의 진입점 역할만 하는것만 불러오면 된다.
자바스크립트 파일끼리 소통하기 때문에
이름 바꾸기
import하는 변수나 함수 이름을 변경하고 싶을 때
import { title as printerTitle, print} from './printer.js';
const title = 'Codeit';
print(title);
여러 개의 모듈을 import할 때 이름이 겹칠 수 있으니 이걸 잘 구분해주는게 좋다
한꺼번에 다루기
모두 export하고 모두 불러올 때는 어떻게 해야함..?
import * as printerJS from './printer.js';
사용할 때는 객체의 형식으로 사용한다.
console.log(printerJS.title);
내보낼 때 선언 시 매번 export 안되게 하려면 어케해야하냐
export { title as printerTitle, print };
default export
export default → 하나의 대상만 내보낼 수 있다.
export default title → 변수나 함수
export default 'codeit' → 값 자체를 보낼 수 도 있다.
export default {title,print} → 하나의 객체 값을 export하게 된다.
→ 그리고 이 말은 export default { title: title, print: print} 인거다.
근데 매번 import할 때 점 표기법으로 접근해야한다.
default는 딱 한번만 사용함.
import{
default as codeit, title } ⇒ default로 import해서 as를 꼭 붙여줘야한다.
다른 사용법
import codeit, {
title as membersTitle, data} 등등 이런 식으로 빼낼 수 있다.
와일드카드로 불러오면 object.default 형식으로 접근할 수 있다.