javascript에서 함수가 호출될 때, 기존 매개변수로 전달되는 인자 값에 대해서 arguments 객체와 this 인자가 함수 내부로 암묵적으로 전달된다.
자바스크립트는 함수 호출 시 어떻게 호출 되는가에 따라서 동적으로 this가 결정된다.
Arrow 함수는 일반적인 this 바인딩과 다르게 Lexical this를 가진다.
EC(Execution Context)가 생성될 때마다 this의 바인딩이 일어나며 우선순위 순으로 나열해보면 다음과 같다.
1. new를 사용했을 때 해당 객체로 바인딩된다.
var name = "global";
function Func() {
this. name = "Func";
this.print = function f() { console.log(this.name)' };
}
var a = new Func();
a.print(); //Func
call, apply, bind와 같은 명시적 바인딩을 사용했을 때 인자로 전달된 객체에 바인딩된다.function func() {
console.log(this.name);
}
var obj = { name: 'obj name' };
func.call(obj); // obj name
func.apply(obj); // obj name
(func.bind(obj))(); // obj name
call과apply는 함수를 호출하는 함수이다. 그러나 그냥 실행하는 것이 아니라 첫 번째 인자에this로 세팅하고 싶은 객체를 넘겨주어this를 바꾸고 나서 실행한다.
bind함수가call,apply와 다른 점은 함수를 실행하지 않는 점이다. 대신 새로운 바인딩한 함수를 생성한다.
var obj = {
name: 'obj name',
print: function p() { console.log(this.name); }
};
obj.print(); // obj name
브라우저의 경우 this는 window 객체이고, 엄격모드에서는 undefined 값이 된다.
따라서 네 가지 바인딩이 아래 우선순위를 따른다.
new 바인딩 > 명시적 바인딩 > 암시적 바인딩 > 기본 바인딩
ES6부터 사용할 수 있는 화살표 함수(arrow function)는 기존의 컨텍스트 바인딩 규칙을 따르지 않는다. 기존 네 가지 컨텍스트는 실행 시점에 바인딩 규칙이 적용된다. 동적 바인딩이라 할 수 있다.
반면 화살표 함수는 실행하지 않고도 바인딩 규칙을 알 수 있다. 이미 정해졌다는 점에서 정적 바인딩이다. 화살표 함수는 코드상 상위 블록의 컨텍스트를 this로 바인딩하는 규칙을 가진다.
따라서 화살표 함수에서는 call, apply, bind로 this를 변경할 수 없다.
window.x = 1;
const normal = function () { return this.x; };
const arrow = () => this.x;
console.log(normal.call({ x: 10 })); // 10
console.log(arrow.call({ x: 10 })); // 1
https://github.com/baeharam/Must-Know-About-Frontend/blob/main/Notes/javascript/this.md
https://iamsjy17.github.io/javascript/2019/06/07/js33_15_this.html
https://wooooooak.github.io/javascript/2018/12/08/call,apply,bind/