[Javascript] this란..

eunniverse·2024년 5월 16일
0

IN Javascript…

  • 자신이 속한 객체나 자신이 생성할 인스턴스를 가리키는 자기 참조 변수
  • 특징
    • 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라진다.
    • 기본적으로 바인딩 되는 건 window 객체다.
      • strict 모드일 때는 undefined 다.
    • 호출하는 함수가 객체의 메서드 면 this 는 상위 scope(??) == 객체 이다.
  • 함수 호출 방식
    • 함수가 어떻게 호출되었는지 따라 this에 바인딩 할 객체가 동적으로 결정된다.

    • 함수 호출

      function car() {
      	console.log('car`s this :: ', this);
      	function bus() {
      		console.log('bus`s this :: ', this);
      	}
      	bus();
      }
      
      car();
      
      ==============================================================
      출력결과 
      car`s this :: window
      bus`s this :: window
      
      ==============================================================
      이유
    • 내부함수는 this 에 window(전역객체) 가 바인딩된다.
      : 전역객체 회피 방법

      1. 객체의 this 를 변수에 저장해 사용
      2. call, apply, bind 로 this 설정
      3. => 화살표 함수 사용
    • 일반 전역함수도 this 에 window(전역객체) 가 바인딩된다.

    • 메서드 호출

      var obj1 = {
        name: 'Lee',
        sayName: function() {
          console.log(this.name);
        }
      }
      
      var obj2 = {
        name: 'Kim'
      }
      
      obj2.sayName = obj1.sayName;
      
      obj1.sayName();
      obj2.sayName();
      
      ==============================================================
      출력결과 
      Lee
      Kim
      
      ==============================================================
      이유
    • 메서드 내부의 this는 해당 메서드를 호출한 객체에 바인딩된다.

    • 생성자 함수 호출

      function Person(name) {
        this.name = name;
      }
      
      var me = new Person('Lee');
      console.log(me);
      
      // new 연산자를 사용하지 않았으므로 생성자 함수 x
      var you = Person('Kim');
      console.log(you);
      
      ==============================================================
      출력결과 
      {name: 'Lee'}
      undefined
    • 동작방식

      1. 빈 객체 생성 및 this 바인딩

      생성자 함수의 코드가 실행되기 전 빈 객체가 생성된다. 이 빈 객체가 생성자 함수가 새로 생성하는 객체이다. 이후 생성자 함수 내에서 사용되는 this는 이 빈 객체를 가리킨다. 그리고 생성된 빈 객체는 생성자 함수의 prototype 프로퍼티가 가리키는 객체를 자신의 프로토타입 객체로 설정한다.

      2. this를 통한 프로퍼티 생성

      생성된 빈 객체에 this를 사용하여 동적으로 프로퍼티나 메소드를 생성할 수 있다. this는 새로 생성된 객체를 가리키므로 this를 통해 생성한 프로퍼티와 메소드는 새로 생성된 객체에 추가된다.

      3. 생성된 객체 반환

      • 반환문이 없는 경우, this에 바인딩된 새로 생성한 객체가 반환된다. 명시적으로 this를 반환하여도 결과는 같다.
      • 반환문이 this가 아닌 다른 객체를 명시적으로 반환하는 경우, this가 아닌 해당 객체가 반환된다. 이때 this를 반환하지 않은 함수는 생성자 함수로서의 역할을 수행하지 못한다. 따라서 생성자 함수는 반환문을 명시적으로 사용하지 않는다.

    • 콜백 호출

      let userData = {
          signUp: '2020-10-06 15:00:00',
          id: 'minidoo',
          name: 'Not Set',
          setName: function(firstName, lastName) {
              this.name = firstName + ' ' + lastName;
          }
      }
      
      function getUserName(firstName, lastName, callback) {
          callback(firstName, lastName);
      }
      
      getUserName('PARK', 'MINIDDO', userData.setName);
      
      console.log('1: ', userData.name);
      console.log('2: ', window.name); 
      
      ==============================================================
      출력결과 
      Not Set
      PARK MINIDDO
      
      ==============================================================
      이유
    • javascript 는 무조건 call by value 이므로 callback 함수 실행 시 setName()의 this는
      window 를 가리킨다.

    • 출력 결과가 PARK MINIDDO 로 나오게 하려면??

      let userData = {
          signUp: '2020-10-06 15:00:00',
          id: 'minidoo',
          name: 'Not Set',
          setName: function(firstName, lastName) {
              this.name = firstName + ' ' + lastName;
          }
      }
      
      function getUserName(firstName, lastName, callback) {
      		/** call(), apply() 를 활용해 this에 userData 를 바인딩해야한다 **/
      		callback.call(userData, firstName, lastName);
      		callback.apply(userData, [firstName, lastName]);
      }
      
      getUserName('PARK', 'MINIDDO', userData.setName);
      
      console.log('1: ', userData.name);
      console.log('2: ', window.name); 
    • 프로토타입

      function Person(name) {
        this.name = name;
      }
      
      Person.prototype.getName = function() {
        return this.name;
      }
      
      var me = new Person('Lee');
      console.log(me.getName()); 
      
      Person.prototype.name = 'Kim';
      console.log(Person.prototype.getName()); 
      
      ==============================================================
      출력결과 
      Lee (체이닝 결과)
      Kim
      
      ==============================================================
      이유
    • this의 프로퍼티를 찾을 때 우선 프로토타입 오브젝트가 없으면, 체이닝에 의해 new 생성자로
      생성된 객체에서 찾는다.

profile
능력이 없는 것을 두려워 말고, 끈기 없는 것을 두려워하라

0개의 댓글