this

mangorovski·2022년 8월 18일
0

Javascript

목록 보기
5/9
post-thumbnail

this 키워드

  • 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 한다.
  • this는 자바스크립트 엔진해 의해 암묵적으로 생성된다.
  • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다.
  • this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.
  • this 바인딩(this가 가리키는 값) 은 함수 호출 방식에 의해 동적으로 결정된다.
    - 바인딩: 식별자와 값을 연결하는 과정으로 this에서는 this와 this를 가리킬 객체를 바인딩

this 바인딩은 동적으로 결정됨

  • this는 함수가 호출되는 방식에 따라 this에 바인딩될 값이 동적으로 결정된다.
  • 객체 리터럴과 생성자 함수의 this

🔶🔸 [객체 리터럴의 메서드 내부에서 this] 🔸🔶

  • this 메서드를 호출한 객체, circle을 가리킨다.
    const circle = {
        radius: 5,
        getDiameter(){
            return 2 * this.radius
        }
    }
    circle.getDiameter() //10

🔶🔸 [생성자 함수 내부의 this] 🔸🔶

  • this는 생성자 함수가 생성할 인스턴스를 가리킨다.

    function Circle(radius){
        this.radius = radius
    }
    Circle.prototype.getDiameter = function(){
        return 2 * this.radius
    }
    
    const circle = new Circle(6)
    console.log(circle.getDiameter())

함수 호출 방식과 this 바인딩

  • 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다.

    일반 함수 호출
    메서드 호출
    생성자 함수 호출
    function.prototype.apply/call/bind 메서드에 의한 간접 호출

    함수 호출 방식this가 가리키는 값 (this 바인딩)
    일반 함수로서 호출전역객체
    메서드로서 호출메서드를 호출한 객체(마침표 앞의 객체)
    생성자 함수로 호출생성자 함수가 미래에 생성할 인스턴스
    apply/call/bind함수 내부의this는 인수에 의해서 결정된다.
  • 일반 함수 내부에서는 this를 사용할 필요가 없기 때문에 strict mode가 적용된 함수의 this는 undefined이다.

일반 함수 호출

  • 기본적으로 this는 전역 객체가 바인딩된다.

  • 일반 함수로 호출하면 this는 전역 객체가 바인딩 된다.

    var value = 1
    const obj= {
        value: 100,
        foo(){
            console.log('foo this: ', this); //{value: 100, foo: ƒ}
            setTimeout(function() {
                console.log('callback this:', this) //window
                console.log('callback this.value:', this.value) //1
            }, 100);
        }
    }
    console.log(obj.foo())
  • 콜백함수의 this가 전역 객체를 바인딩하는 것은 문제가 있다.

  • this가 일치하지 않는다는 것은 중첩함수 또는 헬퍼 함수로 동작하기 어렵게 만든다.

⭕[this 바인딩 일치시키기 위한 방법 1.]

  • 콜백에서 받는 this를 this대신 that을 참조시킨다.
    var value = 1
    const obj = {
        value: 100,
        foo(){
            const that = this; //this 바인딩(obj)을 변수 that에 할당
            setTimeout(() => {
                console.log(that.value) //this대신 that을 참조함
            }, 100);
        }
    }
    console.log(obj.foo()) //100

⭕[this 바인딩 일치시키기 위한 방법 2.]

  • 화살표 함수 내부의 this는 상위 스코프 this를 가리킨다.
      var value = 1
      const obj= {
          value: 100,
          foo(){
              setTimeout(() => {
                  console.log(this.value) //1
              }, 100);
          }
      }
      console.log(obj.foo())

⭕[this 바인딩 일치시키기 위한 방법 3.]

  • function.prototype.apply, bind, call 메서드에 의한 간접 호출
var value = 1
const obj= {
    value: 100,
    foo(){
        setTimeout(function() {
            console.log('callback this.value:', this.value) //100
        }.bind(this), 100);
    }
}
console.log(obj.foo())

메서드 호출

  • 메서드 내부의 this는 메서드를 호출한 객체에 바인딩된다.

  • ❗메서드 내부의 this 메서드가 없는 객체: 메서드를 호출한 객체에 바인딩 됨

  • 메서드는 객체에 포함된 것이 아니라 독립적으로 존재하는 별도 객체이다.

  • 다른 객체의 프로퍼티에 할당하는 것으로 다른 객체의 메서드가 될 수도 있고 일반 변수에 할당하여 일반 함수로 호출될 수도 있다.

    const person = {
        name: 'lee',
        getName() {
            return this.name
        }
    }
    console.log(person.getName()) //lee
    
    const anotherPerson = {
        name: 'kim'
    }
    
    anotherPerson.getName = person.getName
    console.log(anotherPerson.getName()) //kim
    
    const getName = person.getName
    console.log(getName()) //''
  • prototype 또한 객체이므로 메서드를 호출 할 수 있다.

  • 프로토타입 메서드 내부에서 사용된 this도 일반 메서드와 마찬가지로 해당 메서드를 호출한 객체에 바인딩 된다.

    function Person(name){
        this.name = name
    }
    Person.prototype.getName = function(){
        return this.name
    }
    const me = new Person('lee')
    Person.prototype.name = 'Kim'
    console.log(Person.prototype.getName()) //kim

apply, bind, call 메서드

  • function.prototype.apply, bind, call 메서드는 모든 함수가 상속받아서 사용할 수 있다.

  • 각 메서드는 호출할 함수에 인수를 전달하는 방식만 다를 뿐 this로 사용할 객체를 전달하면서 함수를 호출한다.

  • apply, call의 대표적 사용 용도:
    - arguments객체와 같은 유사 배열 객체에 배열 메서드를 사용할 수 없음
    - arguments객체는 배열이 아니기 때문에 Array.prototype.slice 같은 배열 메서드를 사용할 수 없으나 apply, call메서드를 사용하면 이용 가능하다.

  • bind는 함수를 호출하지 않지만, 첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환한다.

  • bind의 대표적 사용 용도:
    - this와 메서드 내부의 중첩 함수 또는 콜백함수의 this가 불일치하는 문제 해결

profile
비니로그 쳌킨

0개의 댓글