320x100
320x100

this가 사라지는 문제

: 객체 메서드가 객체 내부가 아닌 다른 곳에 호출 되면 사라지는 현상

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(user.sayHi, 1000); // Hello, undefined!

: setTimeout의 객체에서 분리된 함수인 user.sayHi가 전달되기 때문

let f = user.sayHi;
setTimeout(f, 1000); // user 컨텍스트를 잃어버림

 

 

 

 

wrapper를 이용한 해결

let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

setTimeout(() => user.sayHi(), 1000); // Hello, John!

: 코드는 간결해지만 취약성이 발생

: setTimeout이 트리거 되기 전에 user가 변경되면 변경된 객체의 메서드를 호출하기 때문

 

 

 

 

bind를 이용한 해결

: 모든 함수는 this를 수정하게 해주는 내장 메서드인 bind를 제공

let boundFunc = func.bind(context);
let user = {
  firstName: "John",
  sayHi() {
    alert(`Hello, ${this.firstName}!`);
  }
};

let sayHi = user.sayHi.bind(user); // (*)

// 이제 객체 없이도 객체 메서드를 호출할 수 있습니다.
sayHi(); // Hello, John!

setTimeout(sayHi, 1000); // Hello, John!

// 1초 이내에 user 값이 변화해도
// sayHi는 기존 값을 사용합니다.
user = {
  sayHi() { alert("또 다른 사용자!"); }
};

 

 

※ bindAll

: 객체에 복수의 메서드가 있고 전체를 전달할 때 메서드를 바인딩 하는 방법

 

 

 

 

인수 바인딩

: this 뿐만 아니라 인수에도 바인딩

: 가독성이 좋은 이름을 가진 독립함수를 만들 수 있음

let bound = func.bind(context, [arg1], [arg2], ...);
function mul(a, b) {
  return a * b;
}

let double = mul.bind(null, 2);

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

 

 

 

 

context 없는 부분적용

: 인수 일부는 고정하고 컨텍스트 this는 고정하지 않는 방법

function partial(func, ...argsBound) {
  return function(...args) { // (*)
    return func.call(this, ...argsBound, ...args);
  }
}

// 사용법:
let user = {
  firstName: "John",
  say(time, phrase) {
    alert(`[${time}] ${this.firstName}: ${phrase}!`);
  }
};

// 시간을 고정한 부분 메서드를 추가함
user.sayNow = partial(user.say, new Date().getHours() + ':' + new Date().getMinutes());

user.sayNow("Hello");
// 출력값 예시:
// [10:00] John: Hello!

 

 

 

 

화살표 함수가 제공하는 독특한 기능

: 어딘가에 함수를 전달하면 함수의 context를 잃을 수 있지만 화살표 함수를 사용하면 잃지 않음

: this가 없어 외부에서 값을 가져오지 않기 때문에, 객체 메서드 안에서 동일 프로퍼티를 대상으로 순회 하는데 사용 가능

let group = {
  title: "1모둠",
  students: ["보라", "호진", "지민"],

  showList() {
    this.students.forEach(
      student => alert(this.title + ': ' + student)
    );
  }
};

group.showList();

: new와 함께 실행할 수 없음

: arguments가 없음

function defer(f, ms) {
  return function() {
    setTimeout(() => f.apply(this, arguments), ms)
  };
}

function sayHi(who) {
  alert('안녕, ' + who);
}

let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred("철수"); // 2초 후 "안녕, 철수"가 출력됩니다.

 

 

 

 

 

Refference

 

함수 바인딩

 

ko.javascript.info

 

화살표 함수 다시 살펴보기

 

ko.javascript.info

300x250
728x90