JavaScript(Spread Operator)

4144 단어 JavaScriptJavaScript

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, 어레이) 

좋은 웹페이지 즐겨찾기