<모던 자바스크립트>
4. 자바스크립트의 문법과 표현
문장과 표현식
문장 (statements)
• 어떤 동작이 일어나도록 작성된 최소한의 코드 덩어리
표현식 (expressions)
• 표현식은 결과적으로 하나의 값이 되는 모든 코드
→ 길이와는 상관없이 결과적으로 하나의 값이 되는 코드를 모두 표현식이라고 할 수가 있다.
표현식이면서 문장, 문장이면서 표현식
// 할당 연산자는 값을 할당하는 동작도 하지만, 할당한 값을 그대로 가지는 표현식이다.
title = 'JavaScript'; // JavaScript
// 함수 호출은 함수를 실행하는 동작도 하지만, 실행한 함수의 리턴 값을 가지는 표현식이다.
sayHi(); // sayHi 함수의 리턴 값
// console.log 메소드는 콘솔에 아규먼트를 출력하는 동작도 하지만, undefined 값을 가지는 표현식이다.
console.log('hi'); // undefined
표현식인 문장 vs 표현식이 아닌 문장
let x;
x = 3;
console.log(if (x < 5) {
console.log('x는 5보다 작다');
} else {
console.log('x는 5보다 크다');
});
const someloop = for (let i = 0; i < 5; i++) {
console.log(i);
};
💡console.log 메소드의 아규먼트로 if문을 전달하거나 someloop 라는 변수에 for 반복문을 할당하게 되면, Error가 발생함
→ 조건문이나 반복문은 값으로 평가되지 않고 오로지 문장으로만 평가되기 때문
조건을 다루는 표현식
조건 연산자
• 조건 ? truthy 할 때 표현식 : falsy할 때 표현식 (삼항 연산자)
// 조건 연산자 (Conditional operator)
const CUT_OFF = 80;
function passChecker(score) {
return score > CUT_OFF ? '합격!' : '불합격! ' ; //truthy 할 때 합격, falsy할 때 불합격
}
console. log(passChecker(75));|
spread 구문
spread 구문
- 여러 개의 값을 하나로 묶은 배열을 다시 각각의 개별 값으로 펼치는 문법
- 배열을 좀 더 편리하게 복사할 수 있다
- 앞에 … 점 3개를 붙여준다
💡Rest Parameter는 여러 개의 아규먼트를 하나의 파라미터로 묶는 방식, spread는 하나로 묶은 배열을 다시 각각의 개별 값으로 펼치는 것
// Spread 구문(Spread Syntax)
const webPublishing = ['HTML', 'CSS'];
const interactiveWeb = webPublishing.slice();//slice() 함수는 배열로 부터 특정 범위를 복사한 값들을 담고 있는 새로운 배열을 만드는데 사용
//const interactiveWeb = [...webPublishing];
interactiveWeb.push('JavaScript');
console. log(webPublishing);
console. log(interactiveWeb); //interactiveWeb에서만 javascript가 보일려면
// slice를 활용하거나 spread활용
함수를 호출할 때 아규먼트로도 활용됨
// Spread 구문(Spread Syntax)
const introduce = (name, birth, job) => {
console. log('안녕하세요! 반갑습니다.');
console. log(`저는 ${name}입니다. `);
console. log('${birth}년 생이고, `);
console. log('직업은 ${job}입니다. `);
console. log( '잘 부탁드립니다 :)');
}:
const myArr = ['코드잇', 2017, '프로그래밍 강사'];
introduce( ... myArr);//myArr를 펼침
💡spread 구문 자체를 값으로 오해하면 안됨 → 하나의 값으로 평가되는 게 아니라 여러 값의 목록으로 평가됨
실습 spread 구문 연습하기 (중요)
const snacks = ['원카칩', '꿀버터칩', '헛스윙칩', '태양칩', '야채시간'];
const drinks = ['사이다', '콜라', '우유', '물', '커피', '레몬에이드'];
function printArguments(...args) {
for (const arg of args) {
console.log(arg);
}
}
// 1. Spread 구문을 활용해서 snacks와 drinks 배열을 각각 mySnacks와 myDrinks 변수에 복사해 주세요
const mySnacks = [...snacks];
const myDrinks = [...drinks];
mySnacks.splice(2, 3);
myDrinks.splice(1);
// 2. Spread 구문을 활용해서 mySnacks와 myDrinks 순서로 두 배열을 합쳐서 myChoice 변수에 할당해 주세요
const myChoice = [...mySnacks, ...myDrinks];
// 3. Spread 구문을 활용해서 myChoice의 각 요소들을 printArguments 함수의 아규먼트로 전달해 주세요
printArguments(...myChoice);
객체 spread하기
객체 Spread하기
const codeit = {
name: 'codeit',
};
const codeitClone = {
...codeit, // spread 문법!
};
console.log(codeit); // {name: "codeit"}
console.log(codeitClone); // {name: "codeit"}
☑️중괄호 안에서 객체를 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
☑️ 객체를 spread할 때는 반드시 객체를 표현하는 중괄호 안에서 활용해야 한다는 점
모던한 프로퍼티 표기법
변수에 할당된 값을 활용해서 프로퍼티를 만들 수도 있음
// 모던한 프로퍼티 표기법
const title = 'Codeit';
const birth = 2017;
const job = '프로그래밍 강사';
const user = {
title,
birth,
job,
};
console. log(user);
//계산된 속성명(computed property name)
const user= {
[표현식]: 값,
};
☑️퀴즈 모던한 프로퍼티 표기법 익히기
1.
const user = {
name: 'codeit',
birth: 2017,
() => {
const date = new Date();
return date.getFullYear() - this.birth + 1;
},
};
메소드는 이름이 없어서 호출할 방법이 없다 따라서 오답
2.
const propertyName = 'birth';
const getJob = () => 'job';
const codeit = {
['topic' + 'Name']: 'Modern JavaScript',
[propertyName]: 2017,
[getJob()]: '프로그래밍 강사',
};
codeit.propertyName; 로 호출하는 것은 (오답)
5번은 점 표기법으로 propertyName이라는 프로퍼티에 접근하는 것이기 때문에 codeit 객체에 존재하지 않는 프로퍼티에 접근하는 방법이고, undefined가 리턴됨
옵셔널 체이닝
function printCatName(user) {
console.log(user.cat?.name);
}
따음표와 마침표를 붙여 사용하는 부분이 바로 옵셔널 체이닝 연산자(?.)
옵셔널 체이닝 연산자 왼편의 프로퍼티 값이 undefined 또는 null이 아니라면 그다음 프로퍼티 값을 리턴하고 그렇지 않은 경우에는 undefined를 반환하는 문법
💡?.은 ?.'앞’의 평가 대상이 undefined나 null이면 평가를 멈추고 undefined를 반환
function printCatName(user) {
console.log(user.cat?.name ?? '함께 지내는 고양이가 없습니다.');
}
const user2 = {
name: 'Young',
}
printCatName(user2); // 함께 지내는 고양이가 없습니다.
Destructuring (구조 분해)
구조분해
• 배열이나 개체 구조를 분해하는 문법
• 배열과 객체에 각각 적용되는 방식에 차이가 있다
☑️ 구조 분해 1 : 배열
// 구조 분해 (Destructuring)
const rank = ['유나', '효준', '민환 ', '재하 ' ] ;
const macbook = rank [0]; // 효준
const ipad = rank[1]; // 84
const airpods = rank[2]; // 민환
const coupon = rank [3]; // 재하
const [macbook, ipad, airpods, coupon] = rank; // 순서대로 할당
const [macbook, ipad, airpods, ...coupon] = rank;
// 남은 나머지 요소를
//마지막 변수의 배열로 할당하는 게 가능하다
const [macbook, ipad, airpods, coupon='없음']=rank;//기본값 할당 가능
console. log(macbook)
console. log(ipad);
console. log(airpods);
console. log(coupon);
💡만약 할당되는 수가 적으면 남은 변수에는 선언이 안되거나 오류가 나는 것이 아니라 undefined 값이 할당됨
let macbook = '효준';
let ipad = '유나';
console. log('MacBook 당첨자:', macbook);
console. log('iPad 당첨자:', ipad);
[macbook,ipad] =[ipad, macbook];
console. log('MacBook 당첨자:', macbook);
console. log('iPad 당첨자:', ipad);
값을 교환할 때도 구조 분해를 사용할 수 있다
실습 배열 구조분해 연습하기
// 1. Destructuring 문법을 활용해서 numbers 배열의 각 요소를 one, two, three라는 변수에 할당해보세요
const numbers = [1, 2, 3];
const [one,two,three]=numbers;
// 2. Destructuring 문법을 활용해서 TV는 livingRoom, 나머지 요소들(배열)은 kitchen 변수에 할당해 주세요
const products = ['TV', '식탁', '냉장고', '전기밥솥', '전자레인지', '오븐', '식기세척기'];
const [livingRoom, ...kitchen]=products;
// 3. Destructuring 문법을 활용해서 두 변수의 값을 서로 바꿔주세요
let firstName = 'Kang';
let lastName = 'Young';
[firstName,lastName]=[lastName,firstName];
// 테스트 코드
console.log(one);
console.log(two);
console.log(three);
console.log(livingRoom);
console.log(kitchen[1]);
console.log(firstName)
☑️ 구조분해 2 : 객체
// 구조 분해 (Destructuring)
const macbook = {
title: '맥북 프로 16형',
price: 3690000,
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
};
// const title = macbook.title;
// const price = macbook.price;
const { title, price } = macbook; //프로퍼티 네임을 적어준다
const { title, ...price } = macbook; // title이 담기고 나머지 price가 담길 때
const { title:product, price } = macbook; //title이름을 product로 변경
console. log(title);
console. log(product);
console. log(price);
💡객체처럼 중괄호로 변수를 묶어줘야 한다
객체에 존재하지 않는 것을 적으면 undefined 값이 할당된다
함수와 Destructuring
💡파라미터 부분에서도 destructuring 가능
// 구조 분해 (Destructuring)
function printWinners ( [macbook, ipad, airpods, ... coupon]) { //파라미터에 구조분해 사용
console. log('이벤트 결과를 알려드립니다!');
console. log(`맥북의 주인공은 '${macbook}'님 입니다. `);
console. log('아이패드의 주인공은 '${ipad}'님 입니다.`);
console. log('에어팟 주인공은 '${airpods}'님 입니다. `);
console. log ('코드잇 3개월 수강권 주인공은');
for (let user of coupon) {
console. log(''${user}"');
}
console. log(`이상 총 ${coupon. length}명 입니다.`);
}
const ranks = ['효준', '효신', '재훈', '소원', '현승' , ' 종훈 ' ] ;
printWinners(ranks);
// 구조 분해 (Destructuring)
const macbook = {
title: '맥북 프로 16형',
price: 3690000,
color: 'silver',
memory: '16GB',
storage: '1TB SSD 저장 장치',
display: '16형 Retina 디스플레이',
};
function printSummary({ title, color, price }) {
console. log(`선택한 상품은 '${title}'입니다.`);
console. log(`색상은 ${color}이며,`);
console. log(`가격은 ${price}원 입니다.`);
};
printSummary(macbook) ;
→ 파라미터를 객체의 형태로 작성한 형태에서 유용하게 사용된다
// 구조 분해 (Destructuring)
const btn = document.querySelector('#btn');
btn.addEventListener('click', ({ target:{classList} }) =>{
classList. toggle('checked');
});
// 구조 분해 (Destructuring)
const btn = document.querySelector('#btn');
btn.addEventListener('click', ( target ) => {
const { classList } = target;
classList.toggle('checked');
});
//중첩 객체 구조 분해 ( Nested Object Destructuring )
퀴즈
1.
const numbers = [5, undefined, null, 3, 1, 7, 0];
const [a, b = 4, c = 2, ...d] = numbers;
console.log(a);
console.log(b);
console.log(c);
console.log(d[2]);
console.log(d[4]);
c는 기본값을 가지고 있으나 numbers에서 할당될 값이 null이다
기본값은 할당될 값이 없거나 undefined일 때 사용된다
2.
// 아래 코드들이 정상적으로 동작하려면 printFavoritSong 함수를 어떻게 선언해야 할까요?
const music1 = { title: '난치병', singer: '하림' };
const music2 = { title: '너의 모든 순간', singer: '성시경' };
const music3 = { title: '무릎', singer: '아이유' };
const music4 = { title: '옛사랑', singer: '이문세' };
const music5 = { title: '한숨', singer: '이하이' };
const music6 = { title: '추억의 책장을 넘기면', singer: '이선희' };
printFavoritSong('영훈', music4);
printFavoritSong('동욱', music1);
printFavoritSong('대위', music3);
printFavoritSong('소원', music2);
printFavoritSong('우재', music5);
printFavoritSong('영준', music6);
//답
function printFavoritSong(name, music) {
console.log(`최근 '${name}'님이 즐겨듣는 노래는 '${music.singer}'의 '${music.title}'이라는 노래입니다.`);
}
function printFavoritSong(name, music) {
const { singer, title } = music;
console.log(`최근 '${name}'님이 즐겨듣는 노래는 '${singer}'의 '${title}'이라는 노래입니다.`);
}
function printFavoritSong(name, { title, singer }) {
console.log(`최근 '${name}'님이 즐겨듣는 노래는 '${singer}'의 '${title}'이라는 노래입니다.`);
}
오답
function printFavoritSong(name, music) { console.log(최근 '${name}'님이 즐겨듣는 노래는 '${music[singer]}'의 '${music[title]}'이라는 노래입니다.); } →
대괄호 표기법으로 접근하려고했지만, 대괄호 안의 표현식이 문자열이 아니기 때문에 올바르게 프로퍼티에 접근할 수 없다
표현식은 대괄호로
표현식이 가지는 값 (ex 문자열 두개의 합) 점으로는 결과.점 접근을해야함
function printFavoritSong(name, [ title, singer ]) { console.log(최근 '${name}'님이 즐겨듣는 노래는 '${singer}'의 '${title}'이라는 노래입니다.); }
→ 파라미터 부분에서 Destructuring 문법을 활용하고 있는데요. 보기 5번은 배열의 Destructuring 문법이기 때문에 제시된 코드 처럼 함수를 호출할 때 전달하는 두 번째 아규먼트가 객체라면 에러가 발생
에러와 에러 객체
자바스크립트는 코드 중 에러가 발생하면 자동으로 에러 객체를 생성한다
→ 에러 객체의 이름을 담고있는 name이라는 프로퍼티와
구체적인 에러 내용을 담고 있는 message라는 프로퍼티가 존재한다
에러객체
- 존재하지 않는 변수나 함수를 호출할 때 발생하는 레퍼런스 에러
- 잘못된 방식으로 자료형을 다루려고 하면 타입에러
- 문법에 맞지 않는 코드를 작성하면 신텍스 에러
// 에러와 에러 객체
console.log( '시작!');
const error = new TypeError('타입에러가 발생했습니다. ');//에러객체를 만드는 것
throw error; // 에러 발생
console.log(error.name);
console.log(error.message);
console.log('끝!');
try catch 문
에러 이후에도 코드가 이어지게하려면 try catch문을 활용해야함
// try catch 문
try {
// 코드
} catch(error) [
// 에러가 발생했을 때 동작할 코드
}
// try catch 문
try {
console.log('에러 전');
const codeit = '코드잇';
console.log(codeit)
codeit = 'codeit';
const language = 'JavaScript';
console. log(language);
} catch (e) {
console. log('에러 후');
console.error(e); -> 실제 에러처럼 출력가능
console. log(e.name);
console. log(e.message);
}
try catch문 활용
실행이 가능한 코드에서 발생한 에러를 예외 exception이라고 부른다
실행 가능한 코드에서 발생한 에러를 다루는 과정을 예외 처리라고 한다
finally문
finally문
finally문은 try...catch문이 끝난 다음에 최종적으로 실행될 코드를 다룰 때 활용
try {
// 실행할 코드
} catch (err) {
// 에러가 발생했을 때 실행할 코드
} finally {
// 항상 실행할 코드
}
try문에서 어떤 코드를 실행할 때 에러 여부와 상관 없이 항상 실행할 코드를 작성
finally문에서의 에러 처리는?
try {
try {
// 실행할 코드
} catch (err) {
// 에러가 발생했을 때 실행할 코드
} finally {
// 항상 실행할 코드
}
} catch (err) {
// finally문에서 에러가 발생했을 때 실행할 코드
}
실습
const quiz1 = {
question: '다음 중 스승의 날과 생일이 같은 인물은 누구일까요?',
example: [ '율곡 이이', '퇴계 이황', '세종대왕', '신사임당'],
answer: 3,
solution: '훈민정음 창제 등 우리나라 문화와 교육발전에 남긴 업적이 가장 큰 인물이라는 평가와 함께, 이 시대의 스승이 세종대왕처럼 존경받았으면 하는 바램으로 세종대왕의 탄신일이 스승의 날로 지정되었습니다.',
};
const quiz2 = {
question: '다음 중 희노애락에 속하지 않는 것은 무엇일까요?',
example: ['사랑', '기쁨', '즐거움'],
answer: 1,
solution: '희노애락에서의 애를 사랑 애(愛)라고 자칫 오해하는 경우가 있지만, 희노애락의 애는 슬플 애(哀)입니다. 기쁨은 기쁠 희(喜), 즐거움은 즐거울 락(樂)에 담겨 있습니다.',
};
function printQuiz({ question, example }) {
try {
let exMsg = '';
for (let i = 0; i < example.length; i++) {
exMsg += `${i + 1}. ${example[i]} `;
}
console.log(question);
console.log(exMsg);
} catch (e) {
console.log(e.name);
}
}
// 테스트 코드
printQuiz(quiz1);
printQuiz(1);
printQuiz("");
printQuiz({});
printQuiz(quiz2);
✍️종합 정리
조건부 연산자 (Conditional operator)
• 삼항 연산자 (Ternary operator)라고도 불리는 이 연산자는 자바스크립트에서 세 개의 피연산자를 가지는 유일한 연산자
const cutOff = 80;
const passChecker = (score) => score > cutOff ? '합격입니다!' : '불합격입니다!';
console.log(passChecker(75));
Spread 구문
• 여러 개의 값을 묶어놓은 배열이나 객체와 같은 값은 바로 앞에 마침표 세 개를 붙여서 펼칠 수 있다
• Spread 구문은 배열이나 객체를 복사하거나 혹은 복사해서 새로운 요소들을 추가할 때 유용하게 활용 될 수 있다 💡참고로 배열은 객체로 펼칠 수 있지만 객체는 배열로 펼칠 수 없다는 부분 기억해둘 것
const members = ['태호', '종훈', '우재'];
const newObject = { ...members };//배열 복사
console.log(newObject); // {0: "태호", 1: "종훈", 2: "우재"}
const topic = {
name: '모던 자바스크립트',
language: 'JavaScript',
}
const newArray = [...topic]; // TypeError! 객체는 배열로 펼칠 수 없음
모던한 프로퍼티 표기법
• 자바스크립트에서 변수나 함수를 활용해서 프로퍼티를 만들 때 프로퍼티 네임과 변수나 함수 이름이 같다면 축약해서 사용할 수 있다
• 메소드를 작성할 때도 다음과 같이 function 키워드를 생략할 수가 있다
• 코드와 같이 대괄호를 활용하면 다양한 표현식으로 프로퍼티 네임을 작성할 수도 있으니까 잘 기억해 두셨다가 유용하게 활용
function sayHi() {
console.log('Hi!');
}
const title = 'codeit';
const birth = 2017;
const job = '프로그래밍 강사';
const user = {
title,
birth,
job,
sayHi,
};
console.log(user); //{title: "codeit", birth: 2017, job: "프로그래밍 강사", sayHi: ƒ}
const user = {
firstName: 'Tess',
lastName: 'Jang',
getFullName() {
return `${this.firstName} ${this.lastName}`;
},
};
console.log(user.getFullName()); // Tess Jang
const propertyName = 'birth';
const getJob = () => 'job';
const codeit = {
['topic' + 'name']: 'Modern JavaScript',
[propertyName]: 2017,
[getJob()]: '프로그래밍 강사',
};
console.log(codeit);
구조 분해 Destructuring
• 배열과 객체와 같이 내부에 여러 값을 담고 있는 데이터 타입을 다룰 때 Destructuring 문법
// Array Destructuring
const members = ['코딩하는효준', '글쓰는유나', '편집하는민환'];
const [macbook, ipad, coupon] = members; // 배열 분해
console.log(macbook); // 코딩하는효준
console.log(ipad); // 글쓰는유나
console.log(coupon); // 편집하는민환
// Object Destructuring
const macbookPro = {
title: '맥북 프로 16형',
price: 3690000,
};
const { title, price } = macbookPro; // 객체 분해
console.log(title); // 맥북 프로 16형
console.log(price); // 3690000
에러와 에러 객체
• 에러 객체는 SyntaxError, ReferenceError, TypeError
throw new TypeError('타입 에러가 발생했습니다.');
try...catch문
• try...catch문은 자바스크립트에서 대표적인 에러 처리 방법
try {
// 실행할 코드
} catch (error) {
// 에러 발생 시 동작할 코드
}
try {
// 실행할 코드
} catch (error) {
// 에러가 발상했을 때 실행할 코드
} finally {
// 항상 실행할 코드
}
'🏃♀️ 대외활동 > Codeit Boost-Node.js' 카테고리의 다른 글
5주차 스터디 자바스크립트 객체 지향 기본기 (1) [코드잇 부스트 백엔드 스터디 ] (0) | 2024.06.04 |
---|---|
4주차 스터디 모던 자바스크립트 (4) [코드잇 부스트 백엔드 스터디 ] (0) | 2024.05.25 |
4주차 스터디 모던 자바스크립트 (2) [코드잇 부스트 백엔드 스터디 ] (0) | 2024.05.25 |
4주차 스터디 모던 자바스크립트 (1) [코드잇 부스트 백엔드 스터디 ] (0) | 2024.05.25 |
3주차 컴퓨터 구조 이해하기 [코드잇 부스트 백엔드 스터디 ] (0) | 2024.05.20 |