지금까지 this를 써주긴했지만 왜 쓰는지? 언제 쓰는지? 적절하게 쓰는 방법을 잘 알지 못하고 썼다. 이번 this를 공부하면서 확실히 알아 this를 적용해야겠다 퐐로퐐로미~~!!!!
this란?
this는 일반적으로 메서드를 호출한 객체가 저장되어 있는 속성입니다. 하지만 this 속성은 메서드를 호출할 때뿐 아니라 일반 함수를 호출할 때도 만들어지며 이벤트 리스너가 호출될 때에도 this 속성이 만들어집니다. 문제는 this 속성에 저장되는 값이 동일한 값이 아니라 각각 다르다는 점입니다.
this의 이해
this 바인딩을 통해 this가 어떤 값과 연결되는지 확인해볼 수 있습니다. 바인딩이란 this의 호출 방식에 따라 this가 특정 '객체'에 연결되는 것입니다. this 바인딩은 1.일반 함수 내부 2.메서드 내부 3.생성자 함수 내부 4.Call, Apply, Bind를 통한 '호출 방식'으로 나눠서 살펴볼 수 있습니다.
2.메서드 호출시 this는 호출한 객체에 바인딩
3.New 바인딩
자바스크립트 함수 앞에 new를 붙여서 실행하며 다음과 같은 일이 일어난다.
new로 반환된 obj 객체를 this 컨택스트와 바인딩 되는 규칙을 따른다.
4.Call, Apply, Bind 메소드 사용시 메서드에 첫 번째 인수로 전달하는 객체에 바인딩
call과 apply 메소드는 기본적으로 함수를 호출하는 역할을 합니다. 그렇다면 기존 함수 호출고 차이점은? 바로 해당 메소드를 사용해 함수를 '실행'하면, 함수의 첫 번째 인자로 전달하는 객체에 this를 '바인딩' 할 수 있다는 것이다.반면, bind는 첫 번째 인자를 this에 바인딩하지만 함수를 '실행하지 않으며', 새로운 함수를 반환합니다.
call
call을 사용하면 함수를 실행하고 함수의 첫 번째 인자로 전달하는 값에 this를 바인딩합니다.
call()는 Function.prototype 객체의 프로퍼티 중의 하나다. logName.call() 형태로 사용할 수 있는 이유다.
call() 함수에 this 컨택스와 바인딩할 객체를 명시할 수 있다. logName() 함수가 실행되면 this는 글로벌 컨택스트가 아닌 obj 객체가 된다. this.name은 obj.name과 같다.
apply
apply를 사용하면 함수를 실행하고 함수의 첫 번째 인자로 전달하는 값에 this를 바인딩합니다. call과 차이점이라면 인자를 배열의 형태로 전달한다는 것입니다. 이때, 인자로 배열 자체가 전달하는 것이 아니라 배열의 요소들이 값으로 전달됩니다.
bind
bind는 함수의 첫 번째 인자에 this를 바인딩한다는 점은 같지만, 함수를 실행하지 않으며 새로운 함수를 반환합니다. 즉, 반환된 새로운 함수를 실행해야 원본 함수가 실행됩니다.
이제 네 가지 바인딩의 우선순위를 정리할수 있다.
1) new로 함수를 호출했는가? 그럼 실행결과 반환되는 값이 this다.
var obj = {}
hello.call(obj) // this === obj
hello.apply(obj) // this === obj
hello.bind(obj)() // this === obj
3) 객체 프로퍼티로 접근하여 함수를 실행했는가? 그럼 이 객체가 this다.
obj.hello() // this === obj
4) 이외의 경우는 this는 전역 객체다.
브라우져의 경우 this는 Window 객체이고 엄격모드에서는 undefined 값이된다.
정리
this는 함수 호출 방식에 따라 동적으로 결정된다. 함수를 일반 함수로 호출할 경우 this는 전역 객체를, 메서드로 호출할 경우 이를 호출한 객체를, 생성자 함수를 호출할 경우 생성자 함수가 생성할 인스턴스를 가르키게 됩니다. call, apply,bind메소드 사용시 메서드에 첫 번째 인수로 전달하는 객체에 바인딩 됩니다.