Javascript
call & apply & bind보다 편리한 방법은?_v3.11
WEB_CREASTORY
2023. 12. 16. 23:17
var func = function (a, b, c, d) {
console.log(this, a, b, c, d);
};
var bindFunc = func.bind({ x:1 }, 4, 5);
// func와 bindFunc의 name 프로퍼티의 차이를 살펴보세요!
console.log(func.name); // func
console.log(bindFunc.name); // bound func
✅ 생성자 내부에서 다른 생성자를 호출(공통된 내용의 반복 제거)
Student, Employee 모두 Person입니다. name과 gender 속성 모두 필요하죠. 그러니 Student와 Employee 인스턴스를 만들 때 마다 세 가지 속성을 모두 각 생성자 함수에 넣기 보다는 Person이라는 생성자 함수를 별도로 빼는게 ‘구조화’에 도움이 더 되겠네요
function Person(name, gender) {
this.name = name;
this.gender = gender;
}
function Student(name, gender, school) {
Person.call(this, name, gender); // 여기서 this는 student 인스턴스!
this.school = school;
}
function Employee(name, gender, company) {
Person.apply(this, [name, gender]); // 여기서 this는 employee 인스턴스!
this.company = company;
}
var kd = new Student('길동', 'male', '서울대');
var ks = new Employee('길순', 'female', '삼성');
- 여러 인수를 묶어 하나의 배열로 전달할 때 apply 사용할 수 있어요.
- apply를 통해 비효율적인 예시를 효율적인 예시로 바꿔봅시다!
//비효율
var numbers = [10, 20, 3, 16, 45];
var max = min = numbers[0];
numbers.forEach(function(number) {
// 현재 돌아가는 숫자가 max값 보다 큰 경우
if (number > max) {
// max 값을 교체
max = number;
}
// 현재 돌아가는 숫자가 min값 보다 작은 경우
if (number < min) {
// min 값을 교체
min = number;
}
});
console.log(max, min);
어떤가요? 코드가 너무 길고 가독성이 떨어집니다. 😭 apply를 적용해보면 어떻게 될까요?
//효율
var numbers = [10, 20, 3, 16, 45];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(null, numbers);
console.log(max, min);
// 펼치기 연산자(Spread Operation)를 통하면 더 간편하게 해결도 가능해요
const numbers = [10, 20, 3, 16, 45];
const max = Math.max(...numbers);
const min = Math.min(...numbers);
console.log(max min);
✅bind 메서드
call과 비슷해 보입니다. 하지만, 즉시 call과는 다르게 즉시 호출하지는 않고 넘겨받은 this 및 인수들을 바탕으로 새로운 함수를 반환하는 메서드라고 보시면 돼요!
목적
1. 함수에 this를 미리 적용해요!
2. 부분 적용 함수 구현할 때 용이합니다.
<예시>
var func = function (a, b, c, d) {
console.log(this, a, b, c, d);
};
func(1, 2, 3, 4); // window객체
// 함수에 this 미리 적용
var bindFunc1 = func.bind({ x: 1 }); // 바로 호출되지는 않아요! 그 외에는 같아요.
bindFunc1(5, 6, 7, 8); // { x: 1 } 5 6 7 8
// 부분 적용 함수 구현
var bindFunc2 = func.bind({ x: 1 }, 4, 5); // 4와 5를 미리 적용
bindFunc2(6, 7); // { x: 1 } 4 5 6 7
bindFunc2(8, 9); // { x: 1 } 4 5 8 9
- name 프로퍼티
- bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 ‘bound’ (수동태)라는 접두어!!(추적하기가 쉽죠!)
- 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
- 내부함수
- 메서드의 내부함수에서 메서드의 this를 그대로 사용하기 위한 방법이에요(이전에는 내부함수에 this를 전달하기 위해 self를 썼었던 것 기억 나시나요?)
- self 등의 변수를 활용한 우회법보다 call, apply, bind를 사용하면 깔끔하게 처리 가능하기 때문에 이렇게 이용하는게 더 낫겠어요 🙂
- 내부함수
var obj = {
outer: function() {
console.log(this); // obj
var innerFunc = function () {
console.log(this);
};
// call을 이용해서 즉시실행하면서 this를 넘겨주었습니다
innerFunc.call(this); // obj
}
};
obj.outer();
this우회, call, apply, bind보다 편리한 방법