객체와 배열은 자바스크립트에서 가장 많이 쓰이는 자료 구조입니다.
키를 가진 데이터 여러 개를 하나의 엔티티에 저장할 땐 객체를,
컬렉션에 데이터를 순서대로 저장할 땐 배열을 사용하죠.
개발을 하다 보면 함수에 객체나 배열을 전달해야 하는 경우가 생기곤 합니다. 가끔은 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 생기기도 하죠.
이럴 때 객체나 배열을 변수로 '분해’할 수 있게 해주는 특별한 문법인 구조 분해 할당(destructuring assignment) 을 사용할 수 있습니다. 이 외에도 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 등에서 구조 분해(destructuring)는 그 진가를 발휘합니다.
of로 순회를 돌아야 key와 value를 한꺼번에 출력할 수 있는데, 위에서는 of로 순회가 불가능함.
이렇게 하면 for of문 사용가능
// 이름과 성을 요소로 가진 배열
let arr = ["rosy", "kim"]
// 구조 분해 할당을 이용해
// firstName엔 arr[0]을
// surname엔 arr[1]을 할당하였습니다.
let [firstName, surname] = arr;
alert(firstName); // rosy
alert(surname); // kim
이제 인덱스를 이용해서 배열에 접근하지 않고도 변수로 이름과 성을 사용할 수 있게 되었다.
split 같은 반환 값이 배열인 메서드 함께 이용해도 좋다.
let a, b, c
[a, b] = [10, 20]
let one, two, three
[one, two, three] = '010-0000-0000'.split('-')
// ['010','0000','0000']
let one1, two1, three1, four1
[one1, two1, three1, four1] = '010-0000-0000'.split('-')
// ['010', '0000', '0000']
[one1, two1, three1, ...four1] = '010-0000-0000-01-02-03'.split('-')
// ['010', '0000', '0000', '01', '02', '03']
console.log(four1)
//['01','02','03']
// 쉼표 사용하여 요소 무시
// 두 번째 요소는 필요하지 않음
let [firstName, , title] = ["민승", "희수", "유정", "도영"];
console.log( title ); // 유정
구조분해할당의 여러 예시들.
아래 문제를 풀어보자~
// 구조분해할당 문제입니다.
data = [10, 20, 30, 40, 50]
// 문제 1
// a, b, c로 각각을 분해할 것입니다.
// a에는 10, b에는 20, 30, 40, c에는 50을 할당해보세요.
//문제 1 답
[a, b, c] = [data[0], [data[1], data[2], data[3]], data[4]];
// 문제 2
// a, b, c로 각각을 분해할 것입니다.
// a에는 10, 20, 30, b에는 40, c에는 50을 할당해보세요.
//문제 2 답
[a, b, c] = [[data[0], data[1], data[2]], data[3], data[4]];
// 문제 3 (정상 작동. 마지막에만 사용할 수 있음)
// a, b, c로 각각을 분해할 것입니다.
// a에는 10, b에는 20 c에는 30, 40, 50을 할당해보세요.
///문제 3 답
[a, b, ...c] = [10, 20, 30, 40, 50]
/// ...로 나머지 요소 가져올 수 있음.
구조분해할당으로 객체도 분해할 수 있다.
let {var1, var2} = {var1:…, var2:…}
// 우측에 분해하고 싶은 객체를, 좌측엔 객체 프로퍼티의 패턴을 넣기
// 추가 예시 보자
let options = {
title: "Menu",
width: 100,
height: 200
};
let {title, width, height} = options;
console.log(title); // Menu
console.log(width); // 100
console.log(height); // 200
// 순서는 중요하지 않다. let {...} 안의 순서가 바뀌어도 동일하게 동작함
let {height, width, title} = { title: "Menu", height: 200, width: 100 }
할당 연산자 좌측에는 조금 더 복잡한 패턴이 올 수도 있다.
options.width를 w라는 변수에 저장해보자! 좌측 패턴의 콜론(:) 사용하기
let options = {
title: "Menu",
width: 100,
height: 200
};
// { 객체 프로퍼티: 목표 변수 }
let {width: w, height: h, title} = options;
// width -> w
// height -> h
// title -> title
alert(title); // Menu
alert(w); // 100
alert(h); // 200
배열 혹은 함수의 매개변수에서 했던 것 처럼, 객체에도 표현식이나 함수 호출을 기본값으로 할당할 수 있다. 물론 표현식이나 함수는 값이 제공되지 않았을 때 평가 혹은 실행됨.
let options = {
title: "Menu"
};
let {width = prompt("width?"), title = prompt("title?")} = options;
alert(title); // Menu
alert(width); // prompt 창에 입력한 값
// 위 예시를 사용하면 width 값만 물어보고 title 값은 물어보지 않습니다.
전개구문 사용법
파라미터가 선언될때 아규먼트가 실행된다
함수 내부에 있는 함수가 파라미터
Parameter -> 매개변수
Argument -> 전달인자,인자
function 함수이름(파라미터){
console.log(파라미터)
console.log('hello world')
return 100
}
let 아규먼트 = 1000
함수이름(아규먼트)
// 내가 파라미터에 전달해 주는것이 아규먼트
// 1000
// hello world
// 100
// 함수의 구조. 함수 이름만 읽고 함수가 실행되는건 나중임
return은 자기가있던 자리에 어떤 값을 줄지
console.log도 함수임. 반환값 + undifined
let z = 100; // 전역변수
function sum(x){
//x는 parameter 면서 지역변수(local val)
let y =50; //y는 지역변수
z= z + y;
return x + y;
}
=>두가지를 잘 구별해야함
function 안녕(){
console.log('hello')
console.log('hello')
console.log('hello')
if (특정조건){
return 100
}
else {
console.log('hello')
console.log('hello')
console.log('hello')
return 1000
}
// return 아래 코드는 실행하지 않습니다.
재사용성
얼마든지 어디서든지 사용 가능함
재사용하지 않을 코드는 함수로 정의하나? => 가능하면 함수로 그래도 만들라
유지보수
3번사항 + 변수의 스코프 제한
구조파악이 용이하다
(참고만)추상화로 개발하는 것이 객체지향 프로그래밍 언어의 언어 철학에 맞다
function 함수1 (a, b, c){
return a + b + c
}
// 콘솔창의 기능이에요. 마지막 라인에 한하여 console.log()를 찍지 않아도 return값을 console창에 출력해줍니다.
함수1(10, 20, 30)
함수1(10, 20, 50)
// 다음 실행 값은?
console.log(함수1(10, 20, 30))
console.log(함수1(10, 20, 50))
// 필요 이상의 아규먼트를 넣었을 때
함수1(10, 20, 30, 40) // Error를 뿜지 않습니다. 60
// 필요 이하의 아규먼트를 넣었을 때
함수1(10, 20)
/*
function 함수1 (a, b, c){
return a + b + String(c)
}
함수1(10, 20) // '30undefined'
*/
함수2('hello', 'world', 10, 20, 30, 40)
function 함수2(a,b,...c){
return Math.max(...c)
}
//40. c가 나머지 요소 전부 다 받아서 처리할 수 있다
function 함수3(a=10, b=20, c=30){
return a + b + c
}
console.log(함수3()) // 60
console.log(함수3(100)) // 150
console.log(함수3(100, 200)) //330
console.log(함수3(100, 200, 300)) //600
console.log(함수3(c=1000)) // 1030이 되어야 하는거 아니에요? => 순서대로 들어감!!!!! 저건 기본값일뿐.
// 1050
console.log(함수3(c=1000, a=2000))
// 3030
얘는 그냥 스킵
함수에서 자기 자신을 호출하는 함수
재귀함수는 주로 반복문을 구현할때 사용한다.
재귀함수의 가장 대표적인 사용 예제는
function factorial(n){
if (n <= 1){ // 종료 조건이 없으면 무한반복이 된다.
return 1
}
return n * factorial(n - 1)
}
factorial(5)
let result = 1;
for (let i = 2; i < 6; i++) {
result *= i
}
console.log(result)
//팩토리얼 함수 뜯어보기
n n <= 1 return
factorial(5) 5 false 5 * factorial(4) = 120
factorial(4) 4 false 4 * factorial(3) = 24
factorial(3) 3 false 3 * factorial(2) = 6
factorial(2) 2 false 2 * factorial(1) = 2
factorial(1) 1 true 1
function reverse(txt){
if (txt.length <= 1) {
return txt
}
return reverse(txt.slice(1)) + txt[0]
}
reverse('hello world');
/*
참고사항
'hello'.slice(1)
'ello'
n txt.length <= 1 return
reverse('hello') false reverse(txt.slice(1)) + 'h' = 'olleh'
reverse('ello') false reverse(txt.slice(1)) + 'e' = 'olle'
reverse('llo') false reverse(txt.slice(1)) + 'l' = 'oll'
reverse('lo') false reverse(txt.slice(1)) + 'l' = 'ol'
reverse('o') true 'o'
*/
function 함수(x,y){
return x+y
}
function 함수2(x,y) => x+y
function 함수2(x,y){
let z= x+y
return x+y
}
let 함수2 = (x,y) => {let z =x+y
return z}
변수가 끌어올려지는 현상
최상위로 끌어올려짐.
선언은 호이스팅 되지만 할당은 호이스팅 되지 않는다
중간고사 점수 구하는 함수
const getAverage = (data) => {
let 중간고사점수 = data.map(i => i.중간고사점수)
let 중간고사점수합 = 중간고사점수.reduce((acc, cur) => acc+cur)
return 중간고사점수합 / data.length;
}
function 평균구하기(data){
let score = data.map((i)=>i.중간고사점수);
let sum = score.reduce((현재값,누적값)=>(현재값+누적값),0);
return sum / data.length;
}
call by value, reference, sharing
폐쇠된 공간(함수)안에 데이터에 접근하기 위한 테크닉
함수 실행 시 클로저에 저장된 x,y 값에 접근하여 값을 계산
지역스코프에서 값을 찾고, 없으면 그 밖에 있는 스코프에서 찾고, 계속해서 찾아 올라가 전역 스코프까지 찾아보는것을 스코프체이닝
=> 어려운 얘기로는 내부 렉시컬 환경에서 찾고, 없으면 전역 렉시컬 환경에서 찾는다.
클로저 예제
암튼 중요하다 네 알겠습니다..