this binding

진성·2022년 5월 29일
0

자바스크립트

목록 보기
22/23

this

this 라는 키워드는 다른 언어에서도 많이 사용된다.
하지만 자바스크립트에서는 다른 언어들과는 다르게 동작을 한다.

대부분의 경우 this의 값은 함수를 호출한 방법에 의해 결정이 된다.
실행중에는 할당으로 설정할 수 없고 함수를 호출할 때 마다 다를 수 있다.
ES5는 함수를 어떻게 호출했는지 상관하지 않고 this 값을 설정할 수 있는 bind 메서드가 추가 되고,
ES6는 스스로의 this 바인딩을 제공하지 않는 화살표 함수가 추가 되었다.
화살표 함수에서의 this는 렉시컬 컨텍스트안의 this 값을 유지한다.

const obj = {
  num : 10,
  foo : function() {
    return this.num
  }
}

console.log(obj.foo()) // 10

this의 참조 값

실행 컨텍스트의 프로퍼티는 비엄격 모드에서 항상 객체를 참조하며, 엄격 모드에서는 어떠한 값이든 될 수 있다.

this는 기본적으로 전역 객체를 참조한다.
브라우저에서는 전역 객체인 window를 참조하고 있다.

console.log(this === window) // ture

a = 10
console.log(window.a) // 10

this.b = "string"
console.log(window.b) // "string"
console.log(b) // "string"

this 함수 호출

함수 내부에서 this의 값은 호출한 방법에 의해 좌우된다.

단순 호출

function window () {
  return this
}

// 브라우저
window() === window // true

// Node.js
window() === global // true

strict mode가 아니며 this의 값이 호출에 이해 설정되지 않으므로, 기본값으로 브라우저에서는 window인 전역 객체를 참조한다.

반면에 strict mode에서 this 값은 실행 문맥에 진입하여 설정되는 값을 유지하므로 다음 예시에서 보여지는 것 처럼 this는 undefined로 남아 있다.

function strict () {
  "use strict"
  return this
}

strict() === undefined // true

bind

ES5에서는 bind가 추가됐다.
bindFunction.bind()를 호출하면 f와 같은 코드와 범위를 가졌지만 this 원본 함수를 가진 새로운 함수를 생성한다.
새 함수의 this는 호출 방식과 상관 없이 영구적으로 bind()의 첫 번째 매개변수로 고정된다.

function bindFunction () {
  return this.a
}

const a = bindFunction({a : 'aBind'})
console.log(a()) // 'aBind'

const b = a.bind({a: 'bBind'}) // bind는 한번만 동작
console.log(b()) // 'aBinde'

화살표 함수

화살표 함수에서 this는 자신을 감싹 정적 범위이다.
전역 코드에서는 전역 객체를 가리킨다.

const obj = this
const foo = () => this
console.log(foo() === obj) true

화살표 함수는 call(), bind(), apply() 를 사용해 호출할 때 this의 값을 정해주더라도 무시한다.
사용할 매개변수를 정해주는 건 문제가 없지만, 첫번째 매개변수는 null을 지정해야 한다.

const obj = {objfunc : foo}
console.log(obj.objfunc() === globalObject) // true

console.log(foo.call(objfunc) === globalObject) // true

foo = foo.bind(objfunc)
console.log(foo() === globalObject) // true

어떠한 방법을 사용하더라도 foothis는 생성 시점의 것으로 설정된다.
다른 함수 내에서 생성된 화살표 함수에도 동일하게 적용된다.
this는 싸여진 렉시컬 컨텍스트의 것으로 유지된다.

객체의 메서드로 사용

함수를 어떤 객체의 메서드로 호출하면 this의 값은 그 객체를 사용한다.

다음 예제에서 o.f()를 실행할 때 O 객체가 함수 내부의 this와 연결이 된다.

const o = {
  num: 10,
  f: function() {
    return this.num;
  }
};

console.log(o.f()); // 10

객체의 메서드로 사용하면 함수가 정의된 방법이나 위치에 전혀 영향을 받지 않는 것에 유의해야한다.
그리고 위와 같이 만들때 선언하지 않고 따로 선언한 함수를 추가하는 것도 가능하다.

const o = { num : 10 }

function foo () {
  return this.num
}

o.f = foo

console.log(o.f()) // 10

이는 함수가 객체의 요소 f로 부터 호출 되는 것만 중요하다는 것을 보여준다.

출처 : mdn

profile
풀스택 진행중...

0개의 댓글