본문 바로가기

Javascript

call & apply & bind보다 편리한 방법은?_v3.11

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입니다. namegender 속성 모두 필요하죠. 그러니 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', '삼성');
  1. 여러 인수를 묶어 하나의 배열로 전달할 때 apply 사용할 수 있어요.
    1. 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
  1. name 프로퍼티
    1. bind 메서드를 적용해서 새로 만든 함수는 name 프로퍼티에 ‘bound’ (수동태)라는 접두어!!(추적하기가 쉽죠!)

  1. 상위 컨텍스트의 this를 내부함수나 콜백 함수에 전달하기
    1. 내부함수
      1. 메서드의 내부함수에서 메서드의 this를 그대로 사용하기 위한 방법이에요(이전에는 내부함수에 this를 전달하기 위해 self를 썼었던 것 기억 나시나요?)
      2. 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보다 편리한 방법