JavaScript

TIL 1030 .concat() vs .push() / setTimeout()

짱닭 2020. 11. 1. 14:04
반응형

concat()

인자로 주어진 배열이나 값들을 기존 배열에 합쳐서 새로운 배열을 리턴
기존 배열은 변경되지 않는다 (immutable)


push()

기존 배열에 마지막 요소를 추가하고, 배열은 새로운 길이 를 갖게되고 요소가 추가된 기존 배열새로운길이_를 리턴
_기존 배열에 새로운 요소를 추가하므로 기존 배열은 요소가 추가된 상태로 변경된다


setTimeout()

setTimeout 메서드는 WindowTimers 객체의 메서드다.

첫번째 인자로 콜백함수를 전달하고,
두번째 인자로 지연시간을 전달해서 사용한다.

아래는 내가 과제를 진행하면서 사용하고 이해한 예시

  step() {
    setTimeout(this.step.bind(this), this.timeBetweenSteps);
    //setTimeout( ()=>{ this.step() }, this.timeBetweenSteps); 윗줄과 같은 의미

    /**
     * function step(){
     *   blabla
     *   this === obj
     *   this.age === obj.age
     * }
     * 
     * this.step.call(obj, ...args)   this를 바인드 후 함수 호출.
     * this.step.apply(this, [...args]) this를 바인드 후 함수 호출.
     * this.step.bind(this)  this를 바인드만 하고 함수 호출 X.
     * 
     * setTimeout(this.step) //호출시 메서드 내부의 this가 window가 됨
     * setTimeout(() => { this.step } )  //호출시 메서드 내부의 this가 window가 됨
     * 
     * setTimeout(() => { this.step }.bind(this) ) //메서드내부의 this가 window가 아니라 bind의 인자 this가 됨. 
     * 
     * 
     * setTimeout(1번째인자(콜백함수) , 2번째인자(시간))
     * 
     * setTimeout(function(){...this} , 1000) //window
     * 
     * setTimeout(function(){...this}.bind(obj) , 1000) //obj
     * 
     */

  }

주석처럼 call, apply, bind의 차이는 다음과 같다

call은 메서드를 호출하면서 this를 바인딩해주고, 두번째 인자부터는 호출할 메서드에 전달할 인자를 넣어준다.
그리고 메서드를 호출한다.

apply는 call과 동일한 기능을 수행하지만, 두번째 인자에 배열로 메서드에 전달할 인자를 넣어준다. 세번째 인자는 없다.
그리고 메서드를 호출한다

bind는 메서드내에서 사용할 this를 바인딩해주는 것은 call과 apply 와 동일하지만,
메서드를 호출하지 않고 바인딩만 수행한다.

결론

setTimeout 메서드는 기본적으로 콜백 함수에서 this를 사용할 경우 기본적으로 this를 window객체로 잡기 때문에,

만약 콜백함수에서 this를 사용해야 하는 경우 그러니까 특정 객체의 메서드를 사용할 때는

setTimeout(obj.drive(), 1000);
//drive() 메서드 내에서 this를 사용한다면?

콜백함수에 반드시 this를 바인딩해서 전달해주어야 한다. 따라서

위 예시에서 이렇게 사용해야한다

setTimeout(obj.drive.bind(obj), 1000);

bind의 인자로 obj의 컨텍스트를 넣으라는 의미다. obj를 그대로 넣으라는게 아니다.

만약 코드가

Class Obj {

  constructor(){
    //...
  }

  drive() {
    setTimeout(this.drive.bind(this), 1000);
  }
}

이렇다면,

클래스 Obj의 인스턴스를
let obj = new Obj();로 만들었을 때,

drive()가 자기 자신을 1초마다 호출하는 구조이기 때문에
setTimeout의 인자는 위처럼 자신의 컨텍스트, 바로 this를 전달받도록 작성해야 한다.

setTimeout(this.drive.bind(this), 1000); 에서
this.drive부분은 인스턴스 obj의 내부 메서드를 호출하는 부분이고,
bind(this)부분은 setTimeout메서드가 this를 window로 잡지 않고
인스턴스 obj를 this로 인식하도록 바인딩 해준 것이다

반응형