whatisthis?

javaScript. 함수 바인딩과 bind() 메서드 본문

WEB STUDY/JAVASCRIPT

javaScript. 함수 바인딩과 bind() 메서드

thisisyjin 2022. 1. 14. 11:32

 

객체의 Method를 콜백(Callback 함수)으로 전달할 때 

this 정보가 사라지는’ 문제가 발생한다.

 

이 문제는 어떻게 해결해야 할까?

 

let Obj = {
	class = 3;
	names = ['lee', 'kim', 'park', 'choi'],
	this.names.forEach( function(name) {
    	alert('class' + this.class + name);     // this 정보가 사라짐
};

 

📌 this가 사라지는 경우

 

- 객체 메서드가 객체 내부가 아닌 다른곳에 전달되어 호출될 때

- 객체의 Method를 콜백(Callback 함수)으로 전달할 때

- 그 외 ) setTimeout(function, 1000) 등의 경우 - thiswindow를 할당함.

 

 

📌📌 bind()

 

모든 함수는 this를 수정하게 해주는 bind() 메서드를 내장하고 있다.

 

bind() 메소드가 호출되면 새로운 함수를 생성한다.

받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공된다.

 

 

- SYNTAX

func.bind(thisArg[, arg1[, arg2[, ...]]])

- thisArg     :   바인딩 함수가 대상 함수(target function)의 this에 전달하는 값.

>> thisArg로 전달된 원시 값은 객체로 변환된다.

 

bind할 인수(arg)가 제공되지 않으면 실행스코프 내의 this는 새로운 함수의 thisArg로 처리된다.

 

- arg1, arg2, ...    :  대상 함수의 인수 앞에 사용될 인수.  (초기 인수)

 

 

 

-> Return값    :  지정한 this값과 초기 인수를 사용하여 변경한 원본함수의 복제본.

 

 

 

 

bind() 함수는 새로운 바인딩한 함수를 만든다.

바인딩한 함수는 원본 함수 객체를 감싸는 함수로, ES 2015에서 말하는 특이 함수 객체(exotic function object)이다.

바인딩한 함수를 호출하면 일반적으로 래핑된 함수가 호출 됩니다.

 

 

let boundFunc = func.bind(context);

func.bind(context)는 함수처럼 호출 가능한 '특수 객체'를 반환한다.

이 객체를 호출하면 this가 context로 고정된 함수인 func를 반환한다.

 

즉, 함수같이 생긴 특수 객체를 반환하고,

그 객체를 호출하여 함수를 반환하는 것.

 

 

 


아래 예제를 살펴보자.

 

this.x = 9;
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
retrieveX();
// 9 반환 - 함수가 전역 스코프에서 호출됐음

전역 스코프인 this에서 변수 x를 불러왔기 때문에

맨 마지막줄에서 retrieveX()의 결과는 9가 된다.

 

 

module 객체와 바인딩된 this가 존재하는 새로운 함수를 생성해보자.

 

 

this.x = 9;
var module = {
  x: 81,
  getX: function() { return this.x; }
};

module.getX(); // 81

var retrieveX = module.getX;
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81

** bind()의 가장 간단한 사용법 - 호출 방법과 관계없이 특정 this 값으로 호출되는 함수를 생성.

 

 

 

 


 

 

 

 

let user = {
  firstName: "John"
};

function func(phrase) {
  alert(phrase + ', ' + this.firstName);
}

// this를 user로 바인딩합니다.
let funcUser = func.bind(user);

funcUser("Hello"); // Hello, John

func.bind(user) func this user '바인딩한 변형’ 이라고 생각하면 된다.

- 인수(Argument), 즉 "Hello"는 원본 함수인 func에 그대로 전달된다.

 

 

 

 

___

 

만약 객체의 this를 그대로 유지하면서

forEach를 사용하고 싶다면

 

forEach( (Callback() {}).bind(this) ) 하면 됨.

 

아래 포스팅 참조.

 

javaScript. ES2015 - Function(함수)

ES6(2015) - 함수(Function) - 화살표 함수(Arrow Function) 추가됨. - 기존 ES5 코드 var object = { name: 'Zero', friends: ['One', 'Two', 'Three'], alertFriends: function() { var self = this; // 객체의..

mywebproject.tistory.com

___

 

 

 

📌📌📌 화살표 함수 (=>)

 

화살표함수에서 => 는 this를 그대로 유지해주는 역할을 한다.

 

forEach( (Callback() {}).bind(this) )를

forEach( Callback ()=> {} ) 로 해주면 된다.

 

 

 


 

< 결론 > 

 

func.bind(context, ...args) this context로 고정되고 인수도 고정된 함수 func을 반환함.

-> 주로 객체 method의 this를 고정해 어딘가에 넘길 때 사용함. (forEach나 setTimeout 등)

 

 

 

+) 추가로, 인수도 바인딩 할 수 있음. (잘 쓰진 않음)

 

let bound = func.bind(context, [arg1], [arg2], ...);

 

 

예제

function mul(a, b) {
  return a * b;
}

let double = mul.bind(null, 2);    // context. 즉 this는 null로 , 첫번째 인수는 2로 고정

alert( double(3) ); // = mul(2, 3) = 6
alert( double(4) ); // = mul(2, 4) = 8
alert( double(5) ); // = mul(2, 5) = 10

- 이런 방식을 부분 적용이라고 함.

>> 기존 함수의 매개변수를 고정하여 새로운 함수를 만들 수 있다.

 

 

❗❗ 주의

this를 사용하지 않더라도 반드시 bind엔 context를 넘겨줘야하므로 null을 사용함.

 

 


 

REFERENCE

 

 

 

 

Function.prototype.bind() - JavaScript | MDN

bind() 메소드가 호출되면 새로운 함수를 생성합니다. 받게되는 첫 인자의 value로는 this 키워드를 설정하고, 이어지는 인자들은 바인드된 함수의 인수에 제공됩니다.

developer.mozilla.org

 

 

this - JavaScript | MDN

JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작합니다. 또한 엄격 모드와 비엄격 모드에서도 일부 차이가 있습니다.

developer.mozilla.org

 

 

함수 바인딩

 

ko.javascript.info