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/