Q. This에 대해서 설명해주세요.
- 사전적 의미 : 이것, 어떠한것을 지칭하는 말
- 자바스크립트에서의 의미: 호출한 실행환경(Execution Context)을 나타내는것
- 멀티 쓰레드일 경우 (ex. 스칼라도 자바스크립트와 비슷하다)
- callback을 호출 → 어떤 thread로 실행이 되는것인가? → 그건 실행환경에 따라 달라진다
- 기본적으로 global(window)에서 호출된다.
1. 자바스크립트에서의 this
-
해당 함수를 호출한 실행 컨텍스트(코드가 실행되는 곳)을 가리킨다. (런타임에 결정)
const test = { prop: 42, func: function () { return this.prop }, } console.log(test.func()) // expected output: 42
-
단,
new
키워드를 만나면, 해당 함수의 this는 생성자를 가르킨다.function Product(name, price) { this.name = name this.price = price } const cheese = new Product('feta', 5)
-
defaults : window (node환경: global)
-
strick-mode에서는 this === 'undefined'
2. this의 정확한 의미
-
다른 언어(Java, Swift, 정적언어...?)
- 생성되는 인스턴스를 가르킨다.
//java public class Foo { public String name; public String color; public Fruit(String name, String color) { this.name = name; this.color = color; } } // swift class Bar { let row: Int, column: Int init(row: Int, column: Int) { self.row = row self.column = column } }
-
js
- es6부터 Class 문법(사실은 함수...)을 지원하기 때문에, 위 언어와 비슷하게 동작한다.
- babel을 활용하여, transpilering 해보면, 아래와 같이 this를 활용하여 호출하게 된다(링크)
class Foo { constructor(name) { this.name = name } foo() { console.log(this.name) } } // babel Compile // this var Foo = /*#__PURE__*/ (function () { function Foo(name) { _classCallCheck(this, Foo) this.name = name } _createClass(Foo, [ { key: 'foo', value: function foo() { console.log(this.name) }, }, ]) return Foo })()
3. call, apply, bind
-
정적바인딩 : bind
-
bind는 this가 지정된
함수
를 리턴한다. -
bind된 함수는 다시 bind 할 수 없다.
const foo = { bar: 1, hello() { console.log(this.bar) }, } // 전역변수 bar = 2 foo.hello() const a = foo.hello.bind(this)
-
-
동적바인딩(default) : call, apply
-
call, apply는 this를 할당한 함수의
실행결과
를 리턴한다.// call function say(phrase) { alert(this.name + ': ' + phrase) } let user = { name: 'John' } // this엔 user가 고정되고, "Hello"는 메서드의 첫 번째 인수가 됩니다. say.call(user, 'Hello') // John: Hello // apply const numbers = [5, 6, 2, 3, 7] const max = Math.max.apply(null, numbers)
-
-
decorator 만들기
-
함수의 역할은 그대로 두고, 기능을 더해준다 (데코레이터 패턴)
function work(a, b) { console.log(a + b) } function spy(func) { return function (...arg) { return func.apply(this, arg) } } work = spy(work) work(1, 2) // 3 work(4, 5) // 9
-
4. 화살표 함수, 일반 함수의 차이
-
일반 함수
- this 호출한 컨텍스트 - arguments 객체를 이용하여, 모든 인자를 받을 수 있음 - new 키워드를 사용할 수 있음
-
화살표 함수
- this 렉시컬 컨텍스트 (선언될때, 이미 this가 할당) - arguments 객체가 없음.. - new 키워드를 사용하여 호출 할 수 없음
5. event handler의 this
// html
<button id="foo">FOO</button>
<button>
<span id="bar">BAR</span>
</button>
$foo.addEventListener('click', function () {
console.log('function this', this) // <button id="foo">FOO</button>
})
$foo.addEventListener('click', () => {
console.log('arrow function this', this) // window
})
$bar.addEventListener('click', function () {
console.log('function this', this) // <span id="bar">BAR</span>
})