728x90
1. 들어가며 : rest, spread는 왜 필요한가?
- '...'을 함수에 매개변수로 쓰면 rest, 객체나 배열에 쓰면 전개구문 spread
- 코드를 줄일 수 있다. (하나하나 다쓰거나, 반복문 쓰지 않아도 됨)
2. 함수의 대량 인수를 처리하는 방법은 2가지
1) arguments (이제 안씀)
- 함수로 넘어온 모든 인수에 접근
- 과거에는 arguments만 쓸 수 있었음 (화살표 함수 못씀)
- es6 환경이면 rest 쓰자
2) 나머지 매개변수 (...rest)
- 함수에 사용
- 보통 매개변수가 1개면 인수 1개만 가져오는데 ... 붙이면 인수 다가져옴 또는 인수가 몇개이든 상관 없음
- 나머지 인수를 다 가져와 배열로 반환
- rest 사용시 주의 점
- ...은 마지막 매개변수에만 붙을 수 있음 e.g) functionN(a,b,c) 여기서 c에만 가능
- 한 함수에 두개 이상의 매개변수에 ... 붙을 수 없음.
// ... 나머지 매개변수(rest parameters)
function showName(...names){ //names 라는 매개변수 하나만 설정되어 있는데 인수 다가져옴)
console.log(names)
}
showName();
showName('Mike');
showName('Mike', 'Sam', 'Jane');
📌예제1: 인수로 받는 모든 숫자를 다 더해보자
1) rest 를 활용한 forEach문
// ... 나머지 매개변수(rest parameters)
// 인수로 받은 것들 다 더하는 함수
function add(...num){
let result = 0;
num.forEach((num)=>{result += num});
console.log(result);
}
add(1,2,3,4); // 10
2) rest 안쓰면? : 배열이 아니여서 forEach 가 성립이 안됨
// ... 나머지 매개변수(rest parameters)
// 인수로 받은 것들 다 더하는 함수
// ... 안쓰고 num으로만 했을 때
function add(num){
let result = 0;
num.forEach((num)=>{result += num});
console.log(result);
}
add(1,2,3,4); // TypeError: num.forEach is not a function // forEach앞에 num이 배열이 아니여서 에러남
- 이렇게 배열을 따로 정의해줘야 함. 즉, 인수 자체를 대량으로 받는게 아닌 대량으로 들어있는 배열을 받아야 함.
let test = [1,2,3,4];
function add(num){
let result = 0;
num.forEach((num)=>{result += num});
console.log(result);
}
add(test); // 10 // 이렇게 따로 배열로 정의해줘야 함. // 즉, 인수 자체를 배열로 받아야 함.
3) reduce 문 활용 (return을 잘 정의해주고 누적값 + 현재값 여기가 += for문과 다른 것 기억)
// 인수로 받은 것들 다 더하는 함수 (reduce 문)
function add(...num){
let result = num.reduce((prev, curr)=>{return prev + curr},0);
console.log(result);
}
add(1,2,3,4); // 10
📌예제2: rest 이용하여 생성자 함수를 만들어라 (this와 new 쓰는거 기억)
// ... 나머지 매개변수(rest parameters)
// rest 이용 유저 객체를 만들어주는 생성자 함수 만들어라.
function UserMaker(name, age, ...skill){
this.name = name;
this.age = age;
this.skill = skill; // 사람마다 스킬의 수는 다르니까
}
const id1 = new UserMaker("Mike", 29, "ppt", "figma", "word");
const id2 = new UserMaker("Mike", 29, "eat", "pray", "love");
const id3 = new UserMaker("Mike", 29, "sleep");
console.log(id1); // UserMaker { name: 'Mike', age: 29, skill: [ 'ppt', 'figma', 'word' ] }
console.log(id2); // UserMaker { name: 'Mike', age: 29, skill: [ 'eat', 'pray', 'love' ] }
console.log(id3); // UserMaker { name: 'Mike', age: 29, skill: [ 'sleep' ] }
3. 전개구문 (Spread syntax) : ...변수명
- 배열, 객체에 사용 가능
- ...변수명 으로 사용
- 변수에 속한 모든 요소 가져옴
- 변수의 요소들 중간에 들어가도 됨 (위치 자유로움)
- 복제가 됨: A 객체를 전개구문으로 B 객체에 넣고 A에서 전달받은 B의 프로퍼티를 수정해도 A에는 영향이 없음
- 배열에 중간에 추가하고 수정하는 것은 메서드를 써야하니 번거로운데 전개구문 쓰면 쉬움
- e.g.) arr.push()//마지막 추가, arr.splice()//특정요소 지우거나 추가, arr.concat()//새로운 배열 추가
// ... 전개 구문 (배열)
let arr1 = [1,2,3]
let arr2 = [4,5,6];
const result = [...arr1, ...arr2];
const result2 = [0,...arr1, 0, ...arr2, 0];
console.log(result); // [ 1, 2, 3, 4, 5, 6 ]
console.log(result2); // [ 0, 1, 2, 3, 0, 4, 5, 6, 0 ]
// ... 전개 구문 (객체)
let user1 = {name: "carl", age: 29}
let newUser = {id: 1, ...user1, location: "seoul"}; // 중간에 전개구문 삽입
console.log(newUser);
// { id: 1, name: 'carl', age: 29, location: 'seoul' }
📌 예제3: 전개 구문의 편안함을 느껴봐라 (배열 편)
// ... 전개 구문 (배열)
// arr1 을 [4,5,6,1,2,3]으로
let arr1 = [1,2,3];
let arr2 = [4,5,6];
// 1번. 전개구문사용
arr1 = [...arr2,...arr1];
console.log(arr1); // [ 4, 5, 6, 1, 2, 3 ]
// 2번. for, unshift 사용하여 만들기
for(let i = arr2.length -1; i > -1; i--){
arr1.unshift(arr2[i])
}
console.log(arr1); // [ 4, 5, 6, 1, 2, 3 ]
// 3번. forEach, unshift 사용하여 만들기
arr2.reverse().forEach((num)=>{
arr1.unshift(num);
})
console.log(arr1); // [ 4, 5, 6, 1, 2, 3 ]
📌 예제4: 전개 구문의 편안함을 느껴봐라 (객체 편)
// ... 전개 구문 (객체)
// 여러 객체를 하나로 모으기 (user 객체에 모으기 + 배열들은 객체 하나에 때려 넣기)
let user = {name: "James", age: 29};
let info = {adress: "seoul"};
let fE = ["JS", "React"];
let lang = ["Korean", "Chinese"];
// 1번. 전개구문으로 만들기 (내 방법) //이건 키 값이 skill 이 아닌 fe, lang 으로 들어감
let skill = {fE: fE, lang: lang}
user ={...user, ...info, ...skill}
console.log(user);
{
name: 'James',
age: 29,
adress: 'seoul',
fE: [ 'JS', 'React' ],
lang: [ 'Korean', 'Chinese' ]
}
// 2번. 전개구문으로 만들기 (앙마님 방법) // 이건 키 값이 skill로 들어가고 하나의 키에 벨류 다들어감.
user = {
...user,
...info,
skill: [...fE, ...lang]
}
console.log(user)
{
name: 'James',
age: 29,
adress: 'seoul',
skill: [ 'JS', 'React', 'Korean', 'Chinese' ]
}
// 3번. 객체메서드 Object.assign 으로 만들기 (내 방법)
let skill = {fE: fE, lang: lang}
user = Object.assign({}, user, info, skill);
console.log(user);
{
name: 'James',
age: 29,
adress: 'seoul',
fE: [ 'JS', 'React' ],
lang: [ 'Korean', 'Chinese' ]
}
// 4번. 객체메서드 Object.assign 으로 만들기 (앙마님 방법)
user = Object.assign({},
user,
info,
{skill: []}, // 빈객체 만들어 forEach로 배열 돌며 push()
);
fE.forEach((item)=>{
user.skill.push(item);
});
lang.forEach((item)=>{
user.skill.push(item);
})
console.log(user);
{
name: 'James',
age: 29,
adress: 'seoul',
skill: [ 'JS', 'React', 'Korean', 'Chinese' ]
}
4. 데이터 타입 (참조형 & 원시형)과 스프레드 연관성
1) 데이터 타입
원시형: string, number, boolean
참조형: 객체, 배열
2) 차이점
원시형은 값을 그대로 할당하지만
참조형은 그 값이 담긴 주소(포인터 라고 함)를 복사함
참조형 즉, 객체나 배열을 복사하고 싶으면 스프레드를 써야 함.
e.g.
const person = {name: "max", age: 20}
const person1 = person; // 이렇게 하면 주소만 복사함. 값은 person이 변경되는 대로 person1 값도 바뀌어 버림
const person1 = {...person} // 이렇게 가져오면 값을 다 가져온 또다른 객체가 됨.
728x90
'html,css,js' 카테고리의 다른 글
[자바스크립트 중급] 클로저 (Closure), 어휘적 환경(Lexical Environment) (0) | 2023.05.09 |
---|---|
[자바스크립트 기초] 변수, 예약어, let, const, `` 벡틱 , typeof, // 주석 (0) | 2023.05.09 |
[자바스크립트 중급] 구조 분해 할당 Destructuring assignment (0) | 2023.05.08 |
[자바스크립트 중급] array method 배열 메소드2 (sort, reduce) (0) | 2023.05.08 |
[자바스크립트 중급] Array method 배열 메소드1 (2) | 2023.05.08 |