원래 함수는 선언한후 호출해야 한다.
호출방법으로는 함수뒤에 ()를 붙이거나 call, apply를 붙이는 방법이 있다.
var example = function (a, b, c) {
return a + b + c;
};
example(1, 2, 3);
example.call(null, 1, 2, 3);
example.apply(null, [1, 2, 3]);
여기 예시가 있다. 위의 값은 모두 6이다.
call과 apply에서 공통적으로 들어가는 null은 무엇인가?
func.call(thisArg[, arg1[, arg2[, ...]]])
fun.apply(thisArg, [argsArray])
바로 this를 대체하는 것이다.
그렇다면 다른예시를 살펴보자.
var obj = {
string: 'zero',
yell: function() {
alert(this.string);
}
};
var obj2 = {
string: 'what?'
};
obj.yell(); // 'zero';
obj.yell.call(obj2); // 'what?'
yell에서 this는 변수 obj를 가리키므로 zero를 출력하는 것은 당연하다.
그러나 yell의 this를 obj2로 바꿀수 있다!?!?!
이처럼 call을 이용하면 this가 향하는 곳을 바꿀 수 있다.
즉, 다른 객체의 함수를 자기 것마냥 사용할 수 있다.
이를 이용하면 함수의 argument를 조작할 수 있다.
arguments는 함수라면 처음부터 갖고 있는 숨겨진 속성이다. 바로 함수에 들어온 인자를 배열 형식으로(배열은 아님, 유사 배열이라고 부른다.) 반환한다.
function example() {
console.log(arguments);
}
example(1, 'string', true); // [1, 'string', true]
위와 같이 보이기에는 배열형식이다.
function example2() {
console.log(arguments.join());
}
example2(1, 'string', true); // Uncaught TypeError: arguments.join is not a function
하지만 배열이 아니기 때문에 배열의 메소드는 사용할 수 없다.
이때 바로 call과 apply가 필요하다.
function example3() {
console.log(Array.prototype.join.call(arguments));
}
example3(1, 'string', true); // '1,string,true'
여기서 Array.prototyle은 배열로 만드는 것을 말한다.
즉, call을 이용해 this를 argument(1, 'string', true)로 바꾸게 한 후 이것을 배열로 만든다. 그후 join메소드를 이용해 합치게 한다. // 결과: '1,string,true'
Array.prototype.join.call(arguments)과 Array.prototype.join.call(arguments, " ")
Array.prototype.join.call(arguments, " ")의 괄호에서 첫번째 인수는 this의 인수이고, 두번째 인수는 join의 인수이다.
잘못된 예: Array.prototype.join('').call(arguments)
bind함수는 함수가 가리키는 this만 바꾸고 호출은 하지 않는다.
예를들어 설명해보자
let user = {
firstName: "John"
};
function func() {
alert(this.firstName);
}
let funcUser = func.bind(user);
funcUser(); // John
funcUser 는 func에 user를 bind했다.
즉, func의 this는 user를 가리킨다.
결과적으로 user.firstName을 출력하므로 "John"이 출력된다.