본문 바로가기

Front-End: Web/JavaScript

[코딩애플] js part 1-7. Spread Operator (...)와 apply / call

반응형

모든 괄호를 없애주는 Spread Operator (...)

자바스크립트에서 펼쳐서 늘어놓고 싶을 때 사용하는 연산자.

대괄호를 다 제거해준다! (뭔가를 늘어놓고 싶을 때)

var 어레이 = ['hello', 'world'];

console.log(어레이); // ["hello","world"]
console.log(...어레이); // hello world

문자에 붙이면 펼쳐준다!

문자도 array처럼 인덱싱이 가능하다. 그래서 문자에도 대괄호를 제거해주고 펼쳐준다고 생각하면 된다.

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

// 문자 인덱싱
console.log(문자[0]); //e

어디에 쓰면 좋을까?

1. array 복사 / 합치기 => ⭐Deep Copy!⭐

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

var c = [...a]; // 복사. [1,2,3]
var c = [...a, ...b]; // 합치기. [1,2,3,4,5]

근데 보기 편해서 쓰기보다는 **Deep copy할 때 유용**하다.

Deep copy

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

a에 있는 값을 b에 복사하고 싶다. 그래서 a를 할당했다. 그러면 a와 b는 각각 [1,2,3]이 된다.

근데 array를 이런 식으로 복사하면 약간 이상하다.

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]

b는 건든 적이 없어서 [1,2,3]이 나오길 기대하는데 왜 4가 추가되지?하는 의문이 생긴다. 그냥 등호로 복사하면 값을 공유하게 된다. 그래서 애초에 두 값은 같은 값을 가지게 된다.

**<u>reference data type(Array, Object)</u>은 이런 식으로 값을 복사하면 값을 공유한다.** 각각 독립적인 값을 가지도록 Array, Object를 복사하려면 Spread operator를 이용해야 한다.

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

a[3] = 4;

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

2. 오브젝트 합치기 => ⭐Deep Copy!⭐

var o2를 만들 때 o1에 있던 거 그대로 넣고 싶은 경우

var o1 = {a: 1, b: 2};
var o2 = {...o1, c: 3};

console.log(o2); // {a: 1, b: 2, c: 3}
  • o1을 o2에 deep copy하려면? spread operator를 쓰세요!

❗유의할 점 - obj를 카피하다가 값 중복이 일어나면?

array와 달리 object는 카피하다가 값이 중복될 수가 있다.

var o1 = {a:1, b:2};
var o2 = {a:2, ...o1};

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

console.log(o2)/ // {a: 2, b: 2}
  • **가장 뒤에 있는 값으로 적용**이 된다.

❗유의할 점 - 아무데나서 쓰면 안돼요!

var o1 = {a:1, b:2};
...o1; // ❗에러 발생

아무데나서 spread operator를 쓰면 안된다. 밖에서 그냥 쓰면 에러가 난다.

<u>**중괄호, 대괄호, 소괄호 안에서만 써야한다.**</u>

3. 함수 파라미터 넣을 때

function 더하기(a,b,c){
    console.log(a + b + c);
}

더하기(1,2,3); // 6

array내의 모든 데이터를 파라미터로 집어넣고 싶은 경우,

function 더하기(a,b,c){
    console.log(a + b + c);
}

var 어레이 = [10,20,30];
더하기(어레이[0], 어레이[1], 어레이[2]); // 60 -> array 해체작업 너무 번거롭다!!

예전에는 어레이에 있는 각각 요소들을 함수에 넣고 싶을 땐 apply라는 이상한 함수를 썼다.

apply

더하기.apply(undefined, 어레이);

이게 <code>더하기(어레이[0], 어레이[1], 어레이[2]);</code> 와 동일한 코드다.

지금은

더하기(...어레이);

방식으로 하면 된다.

apply, call 함수 알아보기

apply

  • 자바스크립트 내장 함수
  • 오브젝트1에 있는 함수를 오브젝트2에 옮겨오고 싶을 때 사용한다.
var person = {
	인사: function(){
        console.log('안녕');
    }
}

person.인사(); // 안녕

여기서 오브젝트 하나를 더 만들어보자.

var person = {
	인사: function(){
        console.log('안녕');
    }
}

var person2 = {
    name: '손흥민'
}

보니까 person 오브젝트에 '인사' 함수를 너무 멋있게 잘 만든 것 같다. 그래서 person2에도 적용해주고 싶다. 근데 person2가 수정이 불가능한 상태면 이게 문제가 된다. 이때 사용하는게 apply 함수다.

함수를 옮겨와서 실행해주세요! => person.인사.apply(person2)

var person = {
	인사: function(){
        console.log('안녕');
    }
}

var person2 = {
    name: '손흥민'
}

person.인사.apply(person2);
person2.인사(); // 안녕

예제로 더 살펴보자.

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

var person2 = {
    name: '손흥민'
}

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

그냥 '인사'라는 함수를 옮겨온 것이다.

call

  • apply / call 는 기능은 동일하다. 그래서 상속기능을 할 때 자주 볼 것이다.
  • 근데 **apply는 파라미터를 array 형태로 집어넣을 수 있다**.
var person = {
	인사: function(){
        console.log(this.name + '안녕');
    }
}

var person2 = {
    name: '손흥민'
}
 
person.인사.apply(person2, [1,2]); // person2를 복붙하고 1, 2를 파라미터로 넣어 실행함
person.인사.call(person2, 1, 2); // person2를 복붙하고 1, 2를 파라미터로 넣어 실행함

그럼 이전에 작성한 이놈은 뭘까?

더하기.apply(undefined, 어레이);

더하기() 함수에 [어레이] 내의 데이터를 파라미터로 넣고 싶을 때 쓴댔는데, **복붙하는 함수 없이 그냥 실행해주세요** 라는 의미다. 그럼 굳이 apply를 쓴 이유는 **파라미터로 array 집어넣는게 가능해서**다.

근데 뭐 이건 예전 방식이니까 이젠 몰라도 된다!

반응형