this (binding arrow)

javascript를 공부하다보면 this의 정의가 다른 언어와 생각보다 다르다라는 것을 느껴 여러 강의를 찾아보고 내용을 정리하고 다시한번 공식문서를 통해서 내용을 정리하였다.

이 부분이 왜 중요한가를 다시 느낀 것은 역시 리엑트를 공부하면서 느꼈다.
this.state
this.setstate 와 같은 방식의 this사용부터 arrow function에서 this를
사용하고 props 방식도 결국 this를 통해서 사용하기에 정리를 해보고자 한다.

arrow function 이전의 this

바인딩 되지 않은 this
화살표 함수가 나오기 전까지의 javascript는,
새로운 함수는, 어떻게 그 함수가 호출되는지에 따라 자신의 this 값을 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function Person() {
// Person() 생성자는 `this`를 자신의 인스턴스로 정의.
this.age = 0;

setInterval(function growUp() {
// 비엄격 모드에서, growUp() 함수는 `this`를
// 전역 객체로 정의하고, 이는 Person() 생성자에
// 정의된 `this`와 다름.
this.age++;
}, 1000);
}

var p = new Person();

function Person() {
var that = this;
that.age = 0;

setInterval(function growUp() {
// 콜백은 `that` 변수를 참조하고 이것은 값이 기대한 객체이다.
that.age++;
}, 1000);
}

arrow function 시 this(call 또는 apply)

화살표 함수는 자신의 this가 없다. 대신 화살표 함수를 둘러싸는 렉시컬 범위(lexical scope)의 this가 사용된다. 화살표 함수는 일반 변수 조회 규칙(normal variable lookup rules)을 따르며,현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수는 바로 바깥 범위에서 this를 찾는것으로 검색을 끝내게 된다.

다음 코드에서 setInterval에 전달 된 함수 내부의 this는 setInterval을 포함한 function의 this와 동일한 값을 화살표 함수에서는 this가 바인딩되지 않았기 때문에, call() 또는 apply() 메서드는 인자만 전달 할 수 있습니다. this는 무시됩니다. (this.base==base)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

var adder = {
base : 1,

add : function(a) {
var f = v => v + this.base;
return f(a);
},

addThruCall: function(a) {
var f = v => v + this.base;
var b = {
base : 2
};

return f.call(b, a);
}
};

console.log(adder.add(1)); // 2
console.log(adder.addThruCall(1)); // 2

바인딩 되지 않은 객체에서의 this

화살표 함수는 arguments 객체를 바인드 하지 않습니다. 때문에, arguments는 그저 둘러싸는 범위(scope) 내 이름에 대한 참조입니다.

1
2
3
4
5
6
7
8
9
10
11
12
var arguments = [1, 2, 3];
var arr = () => arguments[0];

arr(); // 1

function foo(n) {
var f = () => arguments[0] + n;
// foo's implicit arguments binding. arguments[0] is n
return f();
}

foo(1); // 2

화살표 함수는 자신의 arguments 객체가 없지만, 대부분의 경우에 나머지 매개변수를 이용하면 됩니다

1
2
3
4
5
6
function foo(n) {
var f = (...args) => args[0] + n;
return f(2);
}

foo(1); // 3

리엑트에서 this의 사용방식에 대해서도 좀 더 정리를 해볼 생각이다.공식문서를 통해서 한번더 테스트 해보고 공부를 좀 더 해보고자 한다.