자바스크립트 입문_명시적 this 바인딩(call, apply 메소드)

자바스크립트 2021. 5. 5. 15:04

(본 포스팅은 위키북스의 '코어자바스크립트' 책을 공부하면서 작성되었습니다_내돈내산)

 

<call 메서드>

  • call 메서드: 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령
  • call 메서드의 첫번째 인자를 this로 바인딩하고, 이후의 인자들을 호출할 함수의 매개변수로 지정.
  • 함수는 그냥 실행하면 this는 전역객체를 참조하지만, call 메서드를 이용해 임의의 객체를 this로 지정가능.
var func = function (a,b,c){
	console.log(this, a, b, c);
};

func(1,2,3);			// window {...} 1 2 3
func.call({x:1},4,5,6)		// {x:1} 4 5 6
var obj = {
	a: 1,
    method: function(x,y) {
    	console.log(this.a, x, y);
    };
};

obj.method(2, 3);		// 1 2 3
obj.method.call({a:4}, 5, 6);	// 4 5 6

<apply 메서드>

  • call 메서드와 기능적으로 매우 유사함. call 메서드는 첫번째 인자를 제외한 나머지 모든 인자를 호출할 함수의 매개변수로 지정하는 반면, apply 메서드는 두번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정함.
var func = function (a, b, c) {
	console.log(this, a, b, c);
};

func.apply({x:1}, [4,5,6]);		// {x:1} 4 5 6
-------------------------------------------------------------------------------------------
var obj = {
    a: 1,
    method: function(x,y){
    	console.log(this.a, x, y);
    };
};
obj.method.apply({a:4},[5,6])		// 4 5 6

<call/apply 메서드의 활용>

 

- 유사배열객체에 배열 메소드 적용 -

  • 유사배열객체(array-like object)에 배열에서 사용하는 메서드를 적용시킬때.
  • 유사배열객체는 배열과 똑같이 [] 로 쌓여져 있지만 배열과 유사한 형태일뿐이지 실제로 배열이 아니기 때문에 배열에 사용하는 push나 slice같은 메서드를 사용할수가 없음. 이럴때 call이나 apply를 적용시키면 배열메서드를 사용가능함.
  • arguments, NodeList, 문자열과 같은 인덱스와 length 프로퍼티를 지니는 경우 적용이 가능함.(문자열의 경우 length 프로퍼티가 읽기전용이기때문에 원본 문자열에 변경을 가하는 것은 에러가 남.
// 유사배열 객체
var obj = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3
};
Array.prototype.push.call(obj, 'd'); // call(유사배열객체, push인자...)
console.log(obj);		// {0:'a', 1:'b', 2:'c', 3:'d', length:4}

// slice 메서드: 배열의 시작값부터 마지막값의 앞부분까지의 배열 요소를 추출함.(원본의 얕은복사)
var arr = Array.prototype.slice.call(obj); 
console.log(arr);		// ['a','b','c','d'] 배열형태로 반환

 

*** Array.from : 모든종류의 데이터 타입을 배열로 전환(ES6에서 도입됨)

var obj = {
    0: 'a',
    1: 'b',
    2: 'c',
    length: 3
};
var arr = Array.from(obj);
console.log(arr); 		// ['a', 'b', 'c']

- 생성자 내부에서 다른 생성자를 호출 -

  • 생성자 내부에 다른 생성자와 공통된 내용이 있는 경우 call또는 apply를 사용하면 반복을 줄일 수 있음.
function Person(name, gender){
    this.name = name;
    this.gender = gender;
};
function Student(name, gender, school){
    Person.call(this, name, gender);
    this.school = school;
 };
 function Employee(name, gender, company){
     Person.apply(this, [name, gender]);
     this.company = company;
 };
 
 var by = new Student('보영', 'female', '단국대');
 var jn = new Employee('재난', 'male', '구골');

- 여러개의 인수를 묶어 하나의 배열로 전달하고 싶을때 ; apply 활용 - 

  • 여러개의 인수를 받는 메서드에서 하나의 배열로 인수들을 전달하고 싶을때.

(apply를 사용하지 않는 최대/최솟값을 구하기 위한 코드)

var numbers = [10, 20, 3, 16, 45];
var max = min = numbers[0];
numbers.forEach(function(number){
    if (number > max ){
    	max = number;
    }
    if (number < min ){
    	min = number;
    }
});
console.log(max,min); // 45, 3

(call/apply 메소드를 사용한 코드)

var numbers = [10, 20, 3, 16, 45];
var max = Math.max.apply(null, numbers);
var min = Math.min.apply(nukk, numbers);
console.log(max, min) // 45, 3

!참고: (ES6의 spread operator를 이용한경우)

const numbers = [10, 20, 3, 16, 45]
const max = Math.max(...numbers);
const min = Math.min(...numbers);
console.log(max, min); // 45, 3
admin