JavaScript(Spread Operator)

박정호·2022년 3월 30일
0

JS

목록 보기
4/24
post-thumbnail

ES6 Spread Operator

spread operator는 '괄호를 제거해주는 연산자'이고, 함수소괄호, 오브젝트 중괄호내, 어레이 대괄호내에서 보통 사용된다.

다음과 같이 어레이라는 배열 앞에 ...을 입력하면 대괄호가 제거되고 각각의 배열값이 출력된다.

var 어레이 = ['hello', 'world'];
console.log(어레이); // ['hello', 'world']
console.log(...어레이); // 'hello', 'world'

아래와 같이 일반적인 문자값에 ...을 입력할 경우 마치 안보이는 대괄호를 제거하고 각각의 값을 출력하듯이 한개의 문자씩 출력이 된다.

var 문자 = 'hello';
console.log(문자); // hello
console.log(...문자); // h e l l o
console.log('h', 'e', 'l', 'l', 'o'); // h e l l o

Array 합치기 / 복사

c라는 배열에 a와 b배열을 복사하여 합치는 기능이 가능하다.

var a = [1,2,3];
var b = [4,5];
var c = [...a, ...b];

Deep Copy

만약 b배열에 a배열의 값을 복사하고 싶다. 이때 일반적으로 '='을 이용한다.
하지만, a배열에 4를 추가했을 때 b의 배열은 어떨까? 똑같이 값이 추가된 [1,2,3,4]를 출력한다.
왜냐하면 등호(=)를 통해 복사하는 것은 값을 공유한다는 뜻이기 때문이다. b배열에는 a의 [1,2,3]을 원하고 복사한 것인데, a배열의 값추가로 [1,2,3,4]라는 값이 공유가 되버리는 것이다.

var a = [1,2,3];
var b = a;
a[3] = 4;
console.log(a); // [1,2,3,4]
console.log(b); // [1,2,3,4]

따라서, 값을 공유하는 것이 아닌, 각각 독립적인 값을 저장할 수 있도록 spread를 사용하면 된다. [...a]라는 뜻은 b의 빈 배열에 a배열의 대괄호를 제거하여 각각의 배열값을 저장했다는 뜻으로 b라는 배열에 1,2,3 값이 온전히 저장된 것이다. 따라서, a와b배열의 변화에도 서로 영향을 주지 않는다.

var a = [1,2,3];
var b = [...a];
a[3] = 4;
console.log(a); // [1,2,3,4]
console.log(b); // [1,2,3]

Object 합치기, 복사

앞서 본 배열은 []대괄호를 제거한다면, 오브젝트에서는 {}중괄호를 제거한다.
o2객체에 o1의 중괄호를 제거하여 그 안의 객체값들을 가져와 저장하는 것이다.

var o1 = { a : 1, b : 2 };
var o2 = { c : 3, ...o1 };
console.log(o2); // {c: 3, a: 1, b: 2}

만약 중복값이 발생하면?
다음과 같이 a값이 중복된다면 무조건 뒤에 존재하는 a의 값이 저장된다.

var o1 = { a : 1, b : 2};
var o2 = { a : 3, ...o1 }; // {a: 1, b: 2}
console.log(o2);
var o1 = { a : 1, b : 2};
var o2 = { ...o1 , a : 3}; // {a: 3, b: 2}
console.log(o2);

함수의 파라미터에 넣을 때

다음과 같이 함수의 파라미터에 넣는 방법은 다양하다. 이때, case4와 같이 spread를 통해 배열의 값을 가져올 수 있다. 다른 case들에 비해 훨씬 가독성도 좋고, 편하게 사용 가능.

function 더하기(a,b,c){
  console.log(a + b + c)
}
더하기(10,20,30); //case1 그냥 숫자값을 각각 파리미터에 넣을때
var 어레이 = [10, 20, 30]; 
더하기(어레이[0], 어레이[1], 어레이[2]); //case2 인덱싱을 통해 배열값들을 각각 파라미터에 넣을때
더하기.apply(undefined, 어레이);  //case3 apply함수를 통해 배열값들을 각각 파라미터에 넣을때
더하기(...어레이); //case4 배열의 각각 값들을 가져와서 각각 파라미터에 넣을 때

잠깐) apply함수, call함수?

아래의 코드에서 만약 person2객체에서도 person객체의 인사라는 함수를 사용하고 싶다.

var person = {
    인사 : function(){
      console.log(this.name + '안녕')
    }
}
var person2 = {
    name : '손흥민'
}

이때, apply함수를 사용하면 되는데, '이 함수를 저기 오브젝트에 적용 시켜주세요'와 같은 뜻이다. 즉, person객체의 인사함수를 person2에서 적용시키는 함수이다.

person.인사.apply(적용할곳(person2));

조금 더 쉽게 이해하자면, 만약 person.인사()를 출력하면 콘솔창 안의 this.name을 실행하게 되는데, person객체 안에는 name이라는 객체가 존재하지 않는다. 하지만, person.인사.apply(person2)의 경우 person2의 name객체를 가리키게 되므로 '손흥민'이라는 값이 출력된다.

person.인사(); //undefined안녕
person.인사.apply(person2); //손흥민안녕

그리고 인사라는 함수에 파라미터값을 주고 싶다면?

person.인사(파라미터값).apply(person2)

위의 코드와 같이 작성하는 것이 아니라 다음과 같이 작성하면 되겠다.

person.인사.apply(person2,파라미터값)

이때 파라미터값으로 [1,2,3]처럼 배열을 한번에 집어넣을 수 있는 것이 apply이고,
1,2,3을 일반함수처럼 넣을 수 있는 것이 call이다.

person.인사.apply([1,2,3]);
person.인사.call(1,2,3);

따라서, 앞서 보았던 case3의 경우, 파라미터값에 배열을 통째로 넣어주기 위해 apply가 사용되었고, 적용할 곳을 undefined로 작성하여 아무곳에도 실행시키지 않겠다는 뜻이고, 즉 그냥 더하기()함수에 실행되는 것이다.(파라미터값은 주어야 하는데, 적용할 곳 자리는 비워두면 에러가 생기니, undefined를 적는 편법 같은 것)

더하기.apply(undefined, 어레이) 
profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글