JavaScript - 문장(Statements)과 표현식(Expressions)
1. 문장(Statements) 과 표현식(Expressions)
문장(Statements)
Javascript 에서 문장은 어떤 동작이 일어나도록 작성된 최소한의 코드덩어리를 가리킨다.
let x; // 선언문(문장)
x = 3; // 할당문(문장)
// 문장
if (x < 5) {
console.log('x는 5보다 작다');
} else {
console.log('x는 5와 같거나 크다');
}
// 문장
for (let i = 0; i < 5; i++) {
console.log(i);
}
표현식
표현식은 결과적으로 하나의 값이 되는 모든 코드를 가리킨다.
-
어떤 하나의 값을 그대로 작성하는 것 → 표현식
5 // 5 'string' // string
-
연산자를 이용한 연산식 → 하나의 값 → 표현식
5 + 7 // 12 'I' + 'Love' + 'Adam' // I Love Adam true || false // true
-
선언된 변수를 호출, 객체의 프로퍼티에 접근 → 하나의 값 → 표현식
⇒ 결국 길이와는 상관없이 결과적으로 하나의 값이 되는 코드를 모두 표현식이라 한다.
// 할당 연산자는 값을 할당하는 동작도 하지만, 할당한 값을 그대로 가지는 표현식이다. const title = 'Javascript'; const language = { name: 'Python', }; const numbers = [1, 2, 3]; typeof language // object title // Javascript language.name //Python numbers[3] // undefined
- 표현식이면서 문장, 문장이면서 표현식
// 할당 연산자는 값을 할당하는 동작도 하지만, 할당한 값을 그대로 가지는 표현식이다. title = 'Python'; // Python // 함수 호출은 함수를 실행하는 동작도 하지만, 실행한 함수의 리턴 값을 가지는 표현식이다. sayHello(); // sayHello 함수의 리턴 값 // console.log 메소드는 콘솔에 아규먼트를 출력하는 동작도 하지만, undefined 값을 가지는 표현식이다. console.log('Hi'); // undefined
표현식인 문장 Vs 표현식이 아닌 문장
결과적으로 문장은 다시 표현식인 문장과, 표현식이 아닌 문장으로 나눌 수 있고, 이 둘을 구분하는 가장 간단한 방법은 구분하고자 하는 문장을 변수에 할당하거나 어떤 함수의 아규먼트로 전달해보는 것이다.
⇒ console.log
메소드의 아규먼트로 if
문을 전달하거나 어떤 변수에 for
반복문을 할당하게 되면 Error 가 발생하게 된다. === 조건문이나 반복문은 값으로 평가되지 않고 오로지 문장으로만 평가되기 때문
💡 자바스크립트에서는 특별한 경우를 제외하면 일반적으로 표현식인 문장은 세미콜론(
;
) 으로, 표현식이 아닌 문장은 문장 자체의 코드블록(중괄호{}
)로 그 문장의 범위가 구분된다.
3 + 4*2;
console.log('Hello');
for (let arg of arguments) {
// 동작
}
2. 조건 연산자
삼항 연산자
-
조건 ? 조건이 truthy 할 때 표현식 : 조건이 falsy 할 때 표현식;
const con = false const name = con ? 'Adam' : 'Eve' console.log(name) // Eve
-
Python
con = False name = 'Adam' if con else 'Eve' print(name)
3. Spread 구문
여러개의 값을 묶은 하나의 배열을 각각의 개별 값으로 펼치는 문법
const numbers = [1, 2, 3]
console.log(...numbers) // 1 2 3
console.log(1, 2, 3) // 1 2 3
const numbers1 = [1, 2]
const numbers2 = [3, 4]
console.log([...numbers1, ...numbers2]) // [1, 2, 3, 4]
const members = ['adam', 'eve', 'noa'];
const newObj = {...members};
console.log(newObj) // {0: 'adam', 1: 'eve', 2: 'noa'} -> index가 키값으로 담김
객체 Spread
const newObj = {
name: 'adam',
age: 30,
sex: 'male',
from: 'South of Korea'
}
const spreadObj = {
sister: true,
// 객체를 복사해서 spread 할 수 있다.
...newObj
}
console.log(spreadObj)
// {sister: true, name: 'adam', age: 30, sex: 'male', from: 'South of Korea'}
주의 사항
-
Spread 구문을 사용해서 새로운 배열을 만든다거나 함수의 아규먼트로 사용할 수는 없다.
⇒ 객체 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
모던한 프로퍼티 표기법
-
키값이 변수이름 또는 함수이름과 같다면 생략이 가능하다.
// 모던한 프로퍼티 표기법 const firstName = 'Daehwi'; const lastName = 'Kim'; function getFullName(firstName, lastName) { return `${this.firstName} ${this.lastName}` }
const user = { firstName: firstName, lastName: lastName, getFullName: getFullName, }
⬇️
const user = { firstName, lastName, getFullName, }
-
계산된 속성명 (computed property name)
// 표현식의 값을 대괄호[]로 감싸주면 property name으로 사용할 수 있다. const user = { [표현식]: 값, }
const propertyName = 'BirthDay' const getName = () => 'Name'; const adam = { ['my' + 'age']: 30, [propertyName]: 1992, [getName()]: 'DaeHwi Kim' } console.log(adam) // {myage: 30, BirthDay: 1992, Name: 'DaeHwi Kim'}
옵셔널 체이닝 (Optional Chaining)
일반적으로 객체의 프로퍼티는 점표기법을 통해서 접근하게되는데, ECMAScript2020에서 등장한 옵셔널 체이닝을 이용하여 간단하게 객체의 프로퍼티에 접근할 수 있다.
-
옵셔널 체이닝 연산자(
?
) -
?
연산자의 왼편의 프로퍼티 값이null
혹은undefined
값이 아니라면 그다음 프로퍼티 값을 리턴,그렇지 않다면
undefined
를 반환 -
객체의 프로퍼티에 접근할 때 없는 객체를 접근할 때 Error 발생
function printDogName(user) { console.log(user.dog.name); } const user1 = { name: 'Adam', dog: { name: 'Moon', sex: 'Female' } } const user2 = { name: 'Eve' } printDogName(user1) // Moon printDogName(user2) // TypeError: Cannot read properties of undefined (reading 'name')
-
위의 에러를 옵셔널 체이닝(Optional Chaining) 방식과 null 병합 연산자를이용하여 에러 없이 접근
function printDogName(user) { console.log(user.dog?.name ?? '반려견이 없습니다.'); } const user1 = { name: 'Adam', dog: { name: 'Moon', sex: 'Female' } } const user2 = { name: 'Eve' } printDogName(user1) // Moon printDogName(user2) // 반려견이 없습니다.
5. 구조 분해 (Destructuring)
배열이나 객체를 분해하는 문법
1. 배열
-
일반적인 배열을 변수에 할당하는 방법
const ranking = ['유재석', '정준하', '정형돈', '하하', '노홍철']; const macbook = ranking[0]; // 유재석 const iphone = ranking[1] // 정준하 const applewatch = ranking[2]; // 정형돈 const airpods = ranking[3]; // 하하
-
Destructuring
문법을 이용해서 변수에 할당 (배열을 분해해서 할당)const ranking = ['유재석', '정준하', '정형돈', '하하', '노홍철']; const [macbook, iphone, applewatch, airpods] = ranking console.log(macbook) // 유재석 console.log(iphone) // 정준하 console.log(applewatch) // 정형돈 console.log(airpods) // 하하
// 배열의 형식이 아니거나 아무것도 할당하지 않으면 Error가 난다. const [macbook, iphone, applewatch, airpods] = 123; // SyntaxError const [macbook, iphone, applewatch, airpods]; // SyntaxError
-
할당 방법
const ranking = ['유재석', '정준하', '정형돈', '하하', '노홍철']; const [mac, iphone, ...others] = ranking console.log(mac) // 유재석 console.log(iphone) // 정준하 console.log(others) // ['정형돈', '하하', '노홍철']
-
undefined
: 선언된 배열의 갯수가 할당하는 변수보다 적을 경우 할당되는 변수는undefined
로 할당const ranking = ['유재석', '정준하']; const [mac, iphone, other] = ranking console.log(mac) // 유재석 console.log(iphone) // 정준하 console.log(other) // undefined
기본 값을 정하여 할당할 수 있다.
const ranking = ['유재석', '정준하']; const [mac, iphone, other = 'other'] = ranking console.log(mac) // 유재석 console.log(iphone) // 정준하 console.log(other) // other
-
변수를 교환하여 할당할 수 있다.
let mac = 'Adam'; let win = 'Eve'; console.log(mac); // Adam console.log(win); // Eve [mac, win] = [win, mac] console.log(mac); // Eve console.log(win); // Adam
2. 객체 분해
const win = {
title: 'HP Desktop',
price: 700000,
memory: '16GB',
storage: '1TB SSD'
}
// 객체의 프로퍼티에 따른 구조분해
const { title, price, display, mouse = 'Logitech' } = win
console.log(title) // HP Desktop
console.log(price) // 700000
console.log(display) // 객체의 없는 프로퍼티는 undefined로 반환
console.log(mouse) // Logitech -> 기본값으로 선언한 값
- rest parameter 이용 :
...
- 객체의 프로퍼티네임 지정하여 할당 :
title
→product
const { title: product, ...rest } = win console.log(product) // HP Desktop console.log(rest) // {price: 700000, memory: '16GB', storage: '1TB SSD'}
-
computed property name을 이용한 새로운 변수이름으로 할당
const propertyName = 'title'; const { [propertyName]: product } = win console.log(product) // HP Desktop
3. 함수와 Destructuring
-
함수의 파라미터가 배열일때 Destructuring
function printRank([first, second, third, ...rest]) { console.log(first) console.log(second) console.log(third) console.log(rest) } const members = ['유재석', '하하', '정형돈', '정준하', '박명수'] printRank(members) // 유재석 // 하하 // 정형돈 // ['정준하', '박명수']
-
함수의 파라미터가 객체일때 Destructuring
const win = { title: 'HP Desktop', price: 700000, memory: '16GB', storage: '1TB SSD' } function printProduct({ title, price, memory }) { console.log('title: ', title) console.log('price: ', price) console.log('memory: ', memory) } printProduct(win) // title: HP Desktop // price: 700000 // memory: 16GB
6. 에러와 에러 객체
Javascript에서 에러는 에러의 name 과 message로 구분된다.
const error = new SyntaxError('문법 에러가 발생했습니다.')
console.log(error.name) // SyntaxError
console.log(error.message) // 문법 에러가 발생했습니다.
console.log('End'); // End
-
throw
키워를 이용한 Error 발생const error = new SyntaxError('문법 에러가 발생했습니다.') console.log(error.name) // SyntaxError console.log(error.message) // 문법 에러가 발생했습니다. throw error; // Uncaught SyntaxError: 문법 에러가 발생했습니다. // Error가 발생하여 console() 실행되지 않는다. console.log('End');
try catch 문
-
사용법
try { // 코드 } catch (error) { // 에러가 발생했을 떄 동작할 코드 }
-
예시
try { console.log('Before Error') const name = 'adam' console.log(name) name = 'eve' // 재할당으로인한 에러발생 console.log(name) // 위의 에러발생으로 실행되지 않는다. } catch (error) { // 위의 에러 발생으로 실행되어짐 console.log('After Error'); console.error(error) // 에러 발생 console.log(error) // Error객체 프린트 } // Before Error // adam // After Error // TypeError: Assignment to constant variable. (ERROR) // TypeError: Assignment to constant variable.
Try Catch 문의 활용
Error가 발생하면 프로그램이 중단되지만 try catch문을 이용하여 프로그램의 중단 없이 에러를 다룰 수 있다.
-
에러 발생으로 인한 프로그램 중단
function printRank(members) { for (let member of members) { console.log(member) } } const membersA = ['혜정', '지혜', '조민'] printRank(membersA) // 객체를 printRank함수에 아규먼트로 실행하여 Error 발생 const membersB = { name: '하하' } printRank(membersB) // 위의 에러발생으로 실행되지 않음 const membersC = ['길동', '철민', '조준'] printRank(membersC) // 혜정 // 지혜 // 조민 // Uncaught TypeError: members is not iterable
-
try catch
문을 이용하여 프로그램 중단 없이 Error Handlingfunction printRank(members) { try { for (let member of members) { console.log(member) } } catch (error) { console.log(error.name) console.log(error.message) } } const membersA = ['혜정', '지혜', '조민'] printRank(membersA) const membersB = { name: '하하' } printRank(membersB) const membersC = ['길동', '철민', '조준'] printRank(membersC) // 혜정 // 지혜 // 조민 // TypeError // members is not iterable // 길동 // 철민 // 조준
-
try catch
문은 중괄호{}
안에서만 변수선언이 유효하기 때문에 변수 스코프를 잘 생각해야된다.try { const title = 'apple' // try 문에서만 title 변수가 유효 title = 'af' } catch (error) { console.log(title) // Uncaught ReferenceError: title is not defined }
try catch
문은 실행이가능한 코드에서만 작동한다.(SyntaxError는 실행이 되기전 에러가 발생되기 때문에try catch
문은 작동되지 않는다)- 예외처리 (Exception Handling) : 실행 가능한 코드에서 예외처리하는 것
finally 문
finally문은 try문에서 에러가 발생해도 발생하지 않아도 항상 실행되는 구문이다.
try {
// 실행할 코드
} catch (error) {
// 에러가 발생했을 때 동작 코드
} finally {
// 항상 실행할 코드
}
-
finally문에서 에러가 발생했을 시 에러 처리
try { try { // 실행할 코드 } catch (err) { // 에러가 발상했을 때 실행할 코드 } finally { // 항상 실행할 코드 } } catch (err) { // finall문에서 에러가 발생했을 때 실행할 코드 }