에크마스크립트 2015 복습
매개변수 기본값
function hello (name, message = "안녕") {
console.log(`${name}님, ${message}`)
}
hello("구턴", "안녕하세요")
hello("구턴")
전개 구문
값을 펼쳐주는 구문
사용법: "..."
나머지 매개변수로 사용
함수를 선언할 때 몇 개의 인수를 받게 될지 알 수 없는 경우
function addNum (...numbers) {
let sum = 0;
for(let number of numbers)
sum += number;
return sum;
}
console.log(addNum(1,2)); /* 3 */
console.log(addNum(1,2,3,4,5,6,7,8,9,10)); /* 55 */
배열 연결
const animal = ["bird", "cat"]
const fruits = ["apple", "banana", "cherry"]
animal.concat(fruits)
[...animal, ...fruits]
👨🏫 concat은 문자열이나 배열을 붙일 때 사용
전개 구문 사용해 배열 복사
배열과 객체는 참조형 변수입니다.
따라서 배열을 복사하면 값이 아닌 메모리 주소가 복사됩니다.
그 결과, 복사한 배열 값을 수정하면 원본도 수정됩니다.
전개구문을 사용해서 복사하면 주소를 가져오지 않고, 진짜 복사를 합니다.
const fruits = ["apple", "banana", "cherry"]
const mine = [...fruits]
mine
mine[1] = "protein"
mine
객체 프로퍼티
대괄호 표기법
프로퍼티에 공백이 포함되어 있다면 대괄호를 사용하세요.
const book = {
title: "스트렝스 기초",
pages: 500
}
book["published date"] = "250410"
book
계산된 프로퍼티 이름
프로퍼티를 정의할 때, 대괄호 [] 안에 표현식을 넣어 동적으로 키를 만드는 문법
예) fn() 함수를 정의하고, 이를 프로퍼티로 사용
function fn() {
return "result";
}
const obj = {
[fn()] : "함수 키"
}
obj
프로퍼티값 단축
참고: 객체 밖에서 점(.)을 이용해서 프로퍼티 키와 값 지정할 수 있다.
function makeUser (name, age) {
return {
name: name,
age: age
}
}
let user = makeUser("구턴", "100")
user
위와 같이 변수와 프로퍼티 이름이 같으면 아래와 같이 줄여서 사용할 수 있다.
function makeUser (name, age) {
return {
name,
age
}
}
let user = makeUser("구턴", "100")
user
객체에서 심벌키 사용하기
심벌은 한 번 정의하면 값을 변경할 수 없고 유일한 값을 갖습니다.
👍 좋은점
2명 이상의 개발자가 같은 변수나 프로퍼티 이름을 만드는 실수를 방지할 수 있다.
심벌을 사용해 프로퍼티 정의
const id = Symbol("id")
const tel = Symbol("telephone number")
const member = {
name: "9tun",
age: "100",
[id]: 1016,
[tel]: function(){
alert(prompt("전화번호: "));
}
}
for(item in member){
console.log(`${item}: ${member[item]}`)
}
심벌로 작성한 프로퍼티는 for문, Object.key(), Object.value(), Object.entity()로 접근해도 숨겨져있다.
심벌키에 접근하기
그럼 심벌키를 사용한 프로퍼티에는 어떻게 접근할까요?
대괄호를 써서 접근합니다.
심벌키를 사용한 메서드를 실행할 때는 대괄호 오른쪽에 소괄호를 붙입니다.
member[id]
member[tel]()
전역 심벌
전역 심벌 레지스트리에 등록되어 모든 코드에서 공유할 수 있는 유일한 심벌(Symbol)
✅ 전역 심벌은 전역 심벌 레지스트리에 저장된다.
✅ 전역 심벌 레지스트리에는 Symbol.for(), Symbol.keyFor()로 접근한다.
Symbol.for(키)
인수로 받은 키에 해당하는 심벌을 전역 심벌 레지스트리에서 찾아 반환,
만약 심벌이 없다면 만들어서 반환
let tel = Symbol.for("tel") /* 심벌 생성 */
let phone = Symbol.for("tel") /* 생성된 심벌을 반환 */
tel === phone /* true */
Symbol.keyFor(심벌값)
심벌값을 받아서 키를 반환
구조 분해 할당
구조 분해 할당
자료 구조를 분해해서 변수에 할당
배열 구조 분해 할당
let [apple, peach] = ["사과", "복숭아"]
혹은 변수 선언 후 구조 분해도 가능
const fruits = ["사과", "복숭아"]
let [apple, peach] = fruits
일부 값만 구조 분해 할당
let [spring, , fall, ] = ["봄", "여름", "가을", "겨울"]
spring
fall
나머지 변수 사용해 구조 분해 할당
일부 값을 변수로 지정, 나머지 값을 묶어서 하나의 변수에 할당
let [teacher, ...students] = ["Kim", "Lee", "Park", "Choi"]
teacher /* "Kim" */
students /* ["Lee", "Park", "Choi"] */
두 변수 값 교환
기존에는 두 변수의 값을 교환하려면 중간에 임시 변수가 있었어야 한다.
구조 분해를 사용하면 한 번에 교환 가능
[x, y] = [y, x]
객체 구조 분해
{var1, var2} = {var1:값1, var2:값2, ...}
name 키는 name 변수로, age 키는 age 변수로 할당
const member = {
name: "Kim",
age: 25
}
let {name, age} = member
name /* "Kim" */
age /* 25 */
let name, age
{name, age} = {name: "Kim", age: 25}
name /* "Kim" */
age /* 25 */
새 변수 이름
const member = {
name: "Kim",
age: 25
}
let {name : userName, age} = member /* name 키를 userName 변수에 할당 */
nuserName /* "Kim" */
중첩된 객체 구조 분해하기
✅ 중첩 객체
객체 안에 객체를 포함한 객체
아래와 같은 stdent 객체가 있다.
const student = {
name: "도레미",
score: {
history: 85,
science: 94
},
friends: ["Kim", "Lee", "Park"]
}
이 객체를 구조 분해해서 변수에 할당해 보자
let{
name, /* student.name 값 */
score:{
history, /* student.score.history 값 */
science /* student.score.science 값 */
},
friends: [f1, f2, f3] /* friends의 배열 요소를 순서대로 구조 분해 */
} = student
다시말해 위 소스는 아래 한 줄의 소스와 같은 것이다.
let {name, score:{history, science}, friends: [f1, f2, f3]} = student
이제 구조 분해한 값을 불러와 보자
배열을 변형하는 메서드
배열 요소에 같은 함수 적용하기 - map()
map()은 배열 요소에 똑같은 함수를 실행한 후, 그 결과를 새로운 배열로 반환
map(함수(값))
예) 기존 배열에 2를 곱해서 새로운 배열을 생성
let numbers = [1, 2, 3, 4, 5]
let newNumbers = numbers.map(number => number * 2);
newNumbers // [2, 4, 6, 8, 10]
map(함수(값, 인덱스))
map(함수(값, 인덱스, 배열)) // 요소의 값, 인덱스, 원래 배열을 함수의 인수로 사용
let numbers = [1, 2, 3, 4, 5]
let newNumbers = numbers.map((number, index) => index + (number * 3))
newNumbers
👨🏫 여기서 index는 배열의 index입니다.
특정 조건으로 골라내기 - filter()
filter(함수(값))
filter(함수(값, 인덱스))
filter(함수(값, 인덱스, 배열))
예를 들어서 F(=60)를 면한 점수만 골라내보자.
let score = [100, 20, 64, 85, 45, 73]
highScores = score.filter(score => score >= 60)
값 하나로 누적하기 - reduce()
✅ 누산기(accumulator)
배열 원소에 차례대로 함수를 실행해 하나의 결과값을 만들어 하나의 변수에 계속 누적
reduce(함수(누산기, 현잿값, 인덱스, 원래배열), 초기값)
let numbers = [1, 2, 3, 4, 5]
let result = numbers.reduce((total, current) => total + current, 0);
result
Map과 Set
배열과 객체를 보완하기 위해 도입된 Map과 Set에 대해 살펴보자.
등장배경
객체 | 맵과 셋 | |
key | 문자만 사용 가능 | 모든 자료형 사용 가능 (객체, 함수까지) |
프로퍼티 순서 | 없음 | 있음 |
for문 | 사용 불가 | for ... of 사용 가능 |
프로퍼티 갯수 | 모름 | 프로퍼티로 알 수 있음 |
맵
new 예약어로 Map의 객체를 만들고, set() 메서드로 키와 값을 추가
new Map() // Map 객체를 만듭니다.
set(키, 값) // Map 객체에 프로퍼티를 추가합니다.
let bag = new Map()
bag.set("color", "red")
대괄호를 쓰면 만들면서 프로퍼티를 저장할 수도 있다.
new Map() ([
[키1, 값1],
[키2, 값2],
....
]);
let myWire = new Map([
["color", "red"],
["SQ", "0.85sq"],
["length", "1000mm"]
])
myWire
chaining
여러 줄의 소스를 연결해서 작성하는 방법
기존에 아래와 같이 하나씩 set으로 추가하던 프로퍼티를...
bag.set("type", "mini")
bag.set("purpose", "daily")
걍 이렇게 계속 이어서 추가할 수 있음
bag.set("type", "mini").set("purpose", "daily")
맵의 프로퍼티와 메서드
프로퍼티 / 메서드 | 기능 |
size | 맵 요소 개수 |
set(키, 값) | 프로퍼티 추가 |
get(키) | 해당 키의 값을 반환 |
has(키) | 해당 키가 맵에 있는지를 boolean으로 반환 |
delete(키) | 해당 키가 있는 프로퍼티 삭제, 삭제 성공 시 true 반환, 실패 시 false 반환 |
clear() | 맵의 모든 요소 삭제 |
keys() | 각 요소의 키를 모아서 반환 |
values() | 각 요소의 값을 모아서 반환 |
entries() | [키, 값] 형태로 모든 요소 반환 |
keys(), values(), entries()
맵은 iterable 객체입니다.
iterable을 사용해 객체의 구성요소를 하나씩 차례대로 꺼낼 수 있음
let myWire = new Map([
["color", "red"],
["SQ", "0.85sq"],
["length", "1000mm"]
])
myWire.keys()
for (let key of myWire.keys()){
console.log(key)
}
for (let value of myWire.values()){
console.log(value)
}
for (let entry of myWire.entries()){
console.log(entry)
}
set
new Set()
new Set(배열)
배열은 값이 중복될 수 있지만
셋은 키 없이 값만 모아 놓은 것인데, 값이 중복되지 않는다는 게 배열과 다르다.
add(값)
let numSet1 = new Set()
numSet1.add("one")
numSet1.add("two")
혹은 chaining을 사용하면 아래와 같이 쓸 수도 있다.
let numSet1 = new Set().add("one").add("two")
셋의 프로퍼티와 메서드
프로퍼티 / 메서드 | 기능 |
size | 셋 요소 개수 |
add(값) | 셋에 값 추가 |
has(값) | 해당 값이 셋에 있는지를 boolean으로 반환 |
delete(값) | 셋에서 해당 값 삭제 |
clear() | 셋을 비우기 |
let students = new Set()
students.add("구턴")
students.add("소크라테스")
students.add("마르쿠스 아우렐리우스")
students
students.has("구턴")
students.has("니체")
students.clear()
students
keys(), values(), entries()
keys() // 셋에 있는 모든 값 반환
values() // 셋에 있는 모든 값 반환
entries() // [값, 값] 형식으로 모든 값을 반환
let languages = new Set(["js", "c", "python", "c", "js"])
for (let language of languages.values()){
console.log(language)
}
이터레이터와 제너레이터
이터러블 객체
이터러블이란 순서대로 처리할 수 있다는 뜻입니다.
이터러블 객체를 쓰면 편리한 점
다음 기능을 쓸 수 있습니다.
for...of 반복문
전개 연산자(...)
구조 분해 할당
let hi = "hello"
/* 이터러블의 장점을 하나씩 사용해 봅시다! */
/* for...of */
for (let ch of hi){
console.log(ch)
}
/* 전개 연산자 */
let array = [...hi]
array
/* 구조 분해 할당 */
let [ch1, ch2] = hi
ch1
ch2
Symbol.iterator
let arr = [ 1, 2, 3, 4, 5]
let it = arr[Symbol.iterator]()
it
이터레이터 객체와 next()
이터레이터의 next() 메서드로 객체 안 내용을 차례대로 꺼낼 수 있다.
it.next()
it.next()
value는 다음 값인데, 다음으로 꺼낼 값이 없으면 done: true가 된다.
✅ 이터레이터 프로토콜
값을 하나씩 순회할 수 있게 만들어주는 약속
마치 next()를 사용해서 value와 done 프로퍼티 객체를 쌍으로 꺼내는 약속처럼 말이다.
제너레이터 함수
값을 하나씩 생성해서 반환해주는 함수
제너레이터 함수 생성
제너레이터 함수는 일반 함수와 구별하기 위해 function 다음에 *를 붙여서 작성, return 대신 yield을 사용
function* 함수명() {
...
yield
}
제너레이터 객체 생성 방법은 아래와 같이 함수 이름만 지정하면 된다.
객체명 = 함수명()
보통 함수는 함수 내 코드를 멈추지 않고 수행하지만, 제너레이터 함수는 yield 문까지 실행하고 멈춘다.
다시 next()를 실행하면 그 다음 yield문을 실행
function* gen() {
yield 1;
yield 2;
yield 3;
}
제너레이터 객체 생성
gen()을 정의했으니 객체를 만들어 봅시다.
let g1 = gen()
g1
g1 객체가 끝까지 도착해서 다음이 없으면 done: true가 되고,
g1으로 객체를 확인해 보면 closed로서, 순서대로 모두 처리가 끝났음을 알 수 있다.
for...of 문
let g2 = gen()
for (let i of g2) console.log(i)
let g3 = gen()
g3.next()
for (let i of g3) console.log(i)

끝
'JavaScript' 카테고리의 다른 글
비동기 프로그래밍 (0) | 2025.04.26 |
---|---|
HTTP 통신과 JSON (0) | 2025.04.22 |
자바스크립트 객체 (0) | 2025.03.31 |
Javascript의 내장 객체 (0) | 2025.03.27 |
DOM 활용 (0) | 2025.03.26 |