Javascript 함수의 메소드 bind

Posted by negabaro kim on Sunday, March 10, 2019 Tags: javascript   2 minute read

왜 bind를 알아야 할까?

ES6에서 arrow function을 사용시 bind생략이 된다는 혜택을 이해하기 위해서

bind란?

JS function 객체가 기본으로 갖고 있는 메소드

주로 callback 함수에서 많이 쓰인다.

call,apply와 같이 this의 참조값을 바꿀때 쓰인다.

call,apply와 bind의 차이

call,apply는 해당 함수를 실행하는 반면 bind는 실행하지 않고 this의 참조값만 바꾼다.

예제1

var sana = {
  buzzword: '샤샤샤',
  set_buzzword : function() {
    alert(this.buzzword);
  }
};

var KnowingBros = {
  buzzword: '치즈김밥?'
};

var new_sana = sana.set_buzzword.bind(KnowingBros);
//new_sana();

위와 같이 bind를 사용하면 호출은 하지 않고 해당 함수만 반환한다.

반환된 함수를 실행하면 call,apply의 동작과 완전일치

예제2

function multiply(number) {
  'use strict';
  return this * number;
}
// 문맥을 지정해서 바인딩 함수를 생성
var double = multiply.bind(2);
// 바인딩 함수를 실행
double(3);  // => 6
double(10); // => 20

multiply.bind(2)은 double이라는 새로운 함수 객체를 반환한다. 이 바인딩 함수는 this로 숫자 2를 가지고 있다.

multiply와 double 함수는 동일한 코드와 스코프를 가진다.

ES6 arrow function(화살표 함수)으로 bind생략

위 예제와 같이 bind를 사용하면 bind의 인자에 어떤 오브젝트를 넘겨줬느냐에 따라 해당 함수안의 this동적으로 결정되었다.

그러나 ES6부터 생긴 화살표 함수를 이용하면 언제나 상위 스코프의 this를 가리키게 해서

정적으로 this가 참조하는 값을 결정할 수 있게 되었다.

이를 Lexical this라고 한다

화살표 함수의 this 바인딩 객체 결정 방식은 함수의 상위 스코프를 결정하는 방식인 렉시컬 스코프와 유사하다.

덕분에 화살표 함수안에서는 bind를 쓰지 않고 this의 값을 바꿔서 사용할 수 있게 됨.

반대로 말하면 화살표 함수는 call, applay, bind 메소드를 사용하여 this를 변경할 수 없게 되었다.

bind()테크닉

var numbers = {
  array: [3, 5, 10],
  getNumbers: function() {
    return this.array;
  }
};
// 바인딩 함수
var boundGetNumbers = numbers.getNumbers.bind(numbers);
boundGetNumbers(); // => [3, 5, 10]


// 객체로부터 메소드를 추출 = 함수 호출
var directGetNumbers = numbers.getNumbers;
directGetNumbers(); // => undefined 혹은 error(엄격 모드)

this를 사용하는 메소드 구현시 직접 호출이 불가능한데 bind를 이용하면 직접 호출이 가능!

bind() 로 한번 정의하면 new하지 않고선 문맥변경이 불가능

래의 예제는 바인딩 함수를 정의하고, 미리 정의된 문맥을 변경해보는 내용이다.

function getThis() {
  'use strict';
  return this;
}
var one = getThis.bind(1);
// 바인딩 함수 실행
one(); // => 1
// 바인딩 함수에 .apply()와 .call()을 이용해 문맥 변경 시도
one.call(2);  // => 1
one.apply(2); // => 1
// 다시 시도
one.bind(2)(); // => 1
// 바인딩 함수를 생성자 함수로 호출
new one(); // => Object

call,apply,bind등을 이용해 다른this값을 넘겨줘도 변하지 않음을 알 수 있다. new로 호출하자 값에 변동이 생김

https://www.zerocho.com/category/JavaScript/post/57433645a48729787807c3fd