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
300x250
728x90
'Programming > JavaScript' 카테고리의 다른 글
모던 자바스크립트 (객체 프로퍼티 설정) 5-2. 프로퍼티 getter와 setter (0) | 2022.04.23 |
---|---|
모던 자바스크립트 (객체 프로퍼티 설정) 5-1. 프로퍼티 플래그와 설명자 (0) | 2022.04.23 |
모던 자바스크립트 (함수) 4-5. call/apply와 데코레이터, 포워딩 (0) | 2022.04.23 |
모던 자바스크립트 (함수) 4-4. setTiemout과 setInterval을 이용한 호출 스케줄링 (0) | 2022.04.23 |
모던 자바스크립트 (함수) 4-3. 전역 객체 / 함수 표현식 / new Function 문법 (0) | 2022.04.23 |