자바스크립트의 함수는 그냥 함수일뿐만 아니라 함수를 호출할때 new를 붙이면
객체를 만드는 생성자로 쓰일 수 있고 call, bind 등 다양한 사용법이 존재한다.
자바스크립트 함수는 어떤 객체에 종속될 수 있지만 필요에 따라 어떤 객체의 메소드도 될 수 있다.
자바스크립트 파일을 생성하고 다음과 같이 작성해보자.
var kim = {name : 'kim', first : 10, second : 20};
var lee = {name : 'lee', first : 10, second : 10};
// 어떤객체에 속해있지 않는 기능
function sum(){
/*
아래 sum.call(kim)은
this = kim; 이 된다고 생각하면 된다.
*/
return this.first + this.second;
}
// call의 기능 해당 함수를 실행시키는 것과 같다 --> sum();
sum.call(kim);
// 출력
console.log('sum.call(kim) : ', sum.call(kim));
결과
sum.call(kim) : 30
위 call 메소드 원리를 설명하자면
sum.call(kim)에서 함수를 호출할때 첫번째 인자로 this의 값을 kim으로 지정한 것이다.
그리고 sum이라는 함수가 kim의 멤버인 메소드가 된 것이다.
이번엔 lee도 적용시켜 보자.
console.log('sum.call(lee) : ', sum.call(lee));
결과
sum.call(lee) : 20
lee를 인자로 줬기 때문에 this는 이제 lee가 되어 해당 값을 출력해 준다.
여기서 만약 sum이라는 함수가 파라미터 즉 인자를 가지고 있다고 가정해 보자.
var kim = {name : 'kim', first : 10, second : 20};
var lee = {name : 'lee', first : 10, second : 10};
// 인자 추가
function sum(prefix){
// 위에 인자와 나머지 출력
return prefix+(this.first + this.second);
}
// 출력
console.log('sum.call(kim) : ', sum.call(kim));
console.log('sum.call(lee) : ', sum.call(lee));
결과
sum.call(kim) : NaN
sum.call(lee) : NaN
NaN 연산과정에서 잘못된 입력을 받았다고 나온다.
이유는 위에서 우리가 수정한 sum함수의 매개변수 perfix의 값이 없고 해당 값에다 연산을 하니 NaN이 출력되는 것이다.
call의 내부 인자를 설명하자면
첫번째 인자는 그 함수의 내부적으로 this를 정하는 인자를 입력하고,
두번째 인자부터는 우리가 호출하려는 함수에 매개변수로 들어갈 인자값들이 들어가게 된다.
console.log('sum.call(kim) : ', sum.call(kim, "=> "));
console.log('sum.call(lee) : ', sum.call(lee, ": "));
결과
sum.call(kim) : => 30
sum.call(lee) : : 20
이번에는 call처럼 실행할때마다 this를 변경하는 것이 아니라.
내부적으로 고정시키고 싶다면 어떻게 해야될까?
bind를 활용하면 된다.
bind는 호출한 함수를 변경하는 것이 아니라 인자로 받은 조건을 만족하는 새로운 함수를 리턴해준다.
var kim = {name : 'kim', first : 10, second : 20};
var lee = {name : 'lee', first : 10, second : 10};
// 인자 추가
function sum(prefix){
// 위에 인자와 나머지 출력
return prefix+(this.first + this.second);
}
// call
console.log('sum.call(kim) : ', sum.call(kim));
console.log('sum.call(lee) : ', sum.call(lee));
// bind
var kimSum = sum.bind(kim, 'bind ->');
// 바인드로 함수 생성후 호출만 하면됨.
console.log('kimSum()', kimSum());
결과
kimSum() bind ->30