ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바스크립트 딥다이브 9일차
    프론트엔드 2025. 9. 20. 14:27

    this 키워드 

    • 동작을 나타내는 메서드는 자신이 속한 객체의 상태, 즉 프로퍼티를 참조하고 변경할 수 있어야 한다. 
    • 이때 메서드가 자신이 속한 객체의 프로퍼티를 참조하려면 먼저 자신이 속한 객체를 가르키는 식별자를 참조할 수 있어야 한다.
    const circle = {
      radius: 5, 
      
      getDiameter() {
        return 2 * circle.radius
      }
    }
    
    console.log(circle.getDiameter());
    • getDiamter 메서드 내에서 자신이 속한 객체를 가르키는 식별자 circle을 참조하고 있다. 이 참조 표현식이 평가되는 시점은 getDiameter 메서드가 호출되어 함수 몸체가 실행되는 시점이다. 
    • 위 예제의 객체 리터럴은 circle 변수에 할당하기 직전에 평가된다. 자기 자신이 속한 객체를 재귀적으로 참조하는 방식은 일방적이지 않으며 바람직하지도 않다.
    function Circle(radius) {
      // 이 시점에는 생성자 함수 자신이 생성할 인스턴스를 가르키는 식별자를 알 수 없다.
      ????.radius = radius;
    }
    
    Circle.protoype.getDiameter = function () {
      // 이 시점에는 생성자 함수 자신이 생성할 인스턴스를 가르키는 식별자를 알 수 없다.
       return 2 * ????.radius
    }
    
    // 생성자 함수로 인스턴스를 생성하려면 먼저 생성자 함수를 생성해야 한다.
    const circle = new Circle(5);
    • 생성자 함수를 정의하는 시점에는 아직 인스턴스를 생성하기 이전이므로 생성자 함수가 생성할 인스턴스를 가르키는 식별자를 알 수 없다. 
    • 따라서 자신이 속한 객체 또는 자신이 생성할 인스턴스을 가리키는 특수한 식별자가 필요하다 . 이를 위해 자바스크립트는 this라는 특별한 식별자를 제공한다. 
    • this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가르키는 자기 참조 변수다.  this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다. 
    • this 키워드느 자바스크립트에 의해 암묵적으로 생성되며, 코드 어디서든 참조할 수 있다. this가 가르키는 값, 즉 this 바인딩은 함수 호출 방식에 의해 동적으로 결정된다
    this 바인딩
    - 식별자와 값을 연결하는 과정을 바인딩이라 하고, this 바인딩은 this와 this를 가르킬 객체를 바인딩 하는 과정이다
    const circle = {
      radius: 5,
      getDiameter() {
        // this는 메서드를 호출한 객체를 가르킨다
        return 2 * this.radius;
      }
    };
    
    console.log(circle.getDiameter()); // 10
    
    // 생성자 함수
    function Circle(radius) {
      // this는 생성자 함수가 생성할 인스턴스를 가르킨다
      this.radius = radius;
    }
    
    Circle.prototype.getDiameter = function() {
      // this는 생성자 함수가 생성할 인스턴스를 가르킨다
      return 2 * this.radius;
    }
    
    const circle = new Circle(5); 
    console.log(circle.getDiameter()); // 10
    • 객체 리터럴 메서드 내부의 this는 메서드를 호출한 객체 circle을 가르킨다.
    • 자바스크립트에서 this는 함수가 호출되는 방식에 따라 this에 바인딩 될 값 즉 this 바인딩이 동적으로 결정된다.

     

    함수 호출방식과 this 바인딩

    • this 바인딩은 함수 호출 방식, 즉 함수가 어떻게 호출되었는지에 따라 동적으로 결정된다. 
    렉시컬 스코프 this 바인딩
    - 함수 상위 스코프를 결정하는 방식인 렉시컬 스코프는 함수 정의가 평가되어 함수 객체가 생성되는 시점에 상위 스코프를 결정한다. 하지만 this 바인딩은 함수 호출 시점에 결정된다. 
    • 주의사항으로는 함수도 다양한 방식으로 호출이 가능하다는 점인데, 함수를 호출하는 방식은 크게 4가지가 있다
      • 일반 함수 호출
      • 메서드 호출
      • 생성자 함수 호출
      • Function.prototype.apply/call/bind 메서드에 의한 간접 호출
    const foo = function() {
     console.dir(this); 
    }
    
    // 1. 일반 함수 호출
    // foo 함수 내부의 this는 전역 객체 
    foo(); // window;
    
    // 2. 메서드 호출
    // foo 함수의 프로퍼티 값으로 할당하여 호출
    // foo 함수 내부의 this는 메서드를 호출한 객체 obj를 가르킨다
    const obj = { foo }
    
    // 3. 생성자 함수 호출
    // foo 함수를 new 연산자와 함께 생성자 함수로 호출
    // foo 함수 내부의 this는 생성자 함수가 생성한 인스턴스를 가르킴
    new foo(); // foo {}
    
    // 4. Function.prototype.apply/call/bind 메서드에 의한 간접 호출
    // foo 함수 내부의 this는 인수에 의해 결정됨
    const bar = { name : 'bar' };
    
    foo.call(bar); // bar
    foo.apply(bar); // bar

    일반 함수에 의한 호출

    • 기본적으로 this는 전역객체가 바인딩된다.
    • 아래 예제처럼 일반 함수 중첩함수를 호출하면 함수 내부의 this에는 전역 객체가 바인딩 된다.
    • 일반함수에서 this는 의미가 없다.
    function foo() {
     console.log(this); // window;
     function bar() {
       console.log(this); // window;
     }
     
     bar();
    }
    
    foo();
    • 일반 함수로 호출된 모든 함수 내부의 this에는 전역 객체가 바인딩 된다. 

    매서드에 의한 호출

    • 메서드 내부의 this에는 메서드를 호출한 객체, 즉 메서드를 호출할 떄의 메서드 이름 앞에 마침표(.) 연산자 앞에 기술한 객체가 바인딩 된다. 주의할 것은 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체에 바인딩 된다는 것이다.
    const Person = {
     name : 'Lee',
     getName() {
       // 메서드 내부의 this는 메서드를 호출한 객체에 바인딩 된다
       return this.name;
     }
    }
    
    console.log(Person.getName(()); // Lee
    • 위 예제를 보면 getName 메서드 내에서는 Person 객체의 메서드로 정의되어있다. 메서드는 프로퍼티에 바인됭 함수다 
    • 즉 person 객체의 getName 프로퍼티가 가르키는 함수 객체는 person 객체에 포함된 것이 아니라 독립적으로 존재하는 별도의 객체다. getName 프로퍼티가 함수 객체를 가르키고 있을 뿐이다. 

    • 따라서 getName 프로퍼티가 가르키고 있는 함수 객체 즉, getName 메서드는 다른 객체의 프로퍼티에 할당하는 것으로 다른 객체의 메서드가 될 수 있고 일반 변수에 할당하여 일반 함수로 호출도 가능하다. 
    • 메서드 내부의 this는 프로퍼티로 메서드를 가르키고 있는 객체와는 관계가 없고 메서드를 호출한 객체에 바인딩 된다. 
    function Person(name) {
      this.name = name;
    }
    
    Person.prototype.getName = function() {
      return this.name;
    }
    
    const me = new Person('Lee');
    
    console.log(me.getName()); // Lee
    
    Person.prototype.name = 'Kim';
    
    console.log(Person.prototype.getName()); // Kim
    • 위 예제에서 getName 메서드를 호출한 객체는 me다.
    • getName 메서드 내부의 this는 me를 가르키며 this.name은 Lee다

    생성자 함수 호출

    • 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스가 바인딩된다. 
    function Circle(radius) {
      // 생성자 함수의 내부의 this는 생성자 함수가 생성할 인스턴스를 가르킨다
      this.radius = radius;
      this.getDiameter = function () {
        return 2 * this.radius;
      };
    }
    
    const circle1 = new Circle(5);
    
    console.log(circle1.getDiameter()); // 10

     

Designed by Tistory.