FrontEnd/Javascript

자바스크립트의 this

NandaNanda 2024. 2. 29. 17:52

#자바스크립트 this #js this

출처: https://poiemaweb.com/js-this     (this뿐만 아니라 apply/call/bind까지다루고 있다)

요약: Java와 달리  자바스크립트의 경우 Java와 같이 this에 바인딩(식별자와 데이터를 연결)되는 객체는 한가지가 아니라 해당 함수 호출 방식에 따라 this에 바인딩되는 객체가 달라진다.  함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정되는 것이 아니고, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다(하지만 내 생각에는 어떻게 호출했는가 뿐만 아니라 어떻게 선언 되었는가도 영향을 주는것 같다. 아래의 예시를 보면 객체안에 함수표현식 방식으로 선언된 함수에서의 this는 해당 객체를 의미하지만 화살표 함수 방식으로 선언된 함수에서의 this는 브라우저상에서의 window객체를 의미하기 때문이다).

(함수의 상위 스코프를 결정하는 방식인 렉시컬 스코프(Lexical scope)는 함수를 선언할 때 결정된다. this 바인딩과 혼동하지 않도록 주의하기 바란다.) (복습. 클로저란? 함수가 선언될때 자신의 렉시컬 환경(상위 스코프)을 기억하는 함수)

/**
 * 아래의 예시를 정리하면 이렇다. 독립적인 함수는 그것이 함수표현식이든 화살표
 * 함수이든 this는 window객체를 반환하지만 객체안에 쓰인 함수는 그것이 함수선언문
 * 이면 this는 해당 객체를 의미하지만 화살표함수이면 window객체를 의미한다
 */
const hero={
    name:'han',
    hp:100,
    func: function(){
        this.hp-=10;
        console.log(this.hp);
        console.dir(this);//이 객체에 대한 속성정보 모두 출력
    },
    showState:()=>{
        console.log(this.hp);//오류는 안나지만 undefined출력
        console.log(this);//빈 객체 출력. 브라우저에서는 window객체출력
    }
}
hero.func();
hero.showState();




var foo = function () {
    console.dir(this);
  };

  // 1. 함수 호출
  foo(); // Node에서 하면 빈객체 출력. 브라우저에서 실행하면 window 객체출력
  // window.foo();
 
let bar=()=>{
    console.dir(this);//빈객체 출력. 브라우저에서 실행하면 window객체 출력
}
bar();

 

전역객체는 전역변수를 프라퍼티로 소유한다(window.ga). 글로벌 영역에서 선언된 함수는 전역객체의 메서드이다(window.foo()).

var ga = 'Global variable';//전역객체(window)가 프라퍼티로 소유하는 전역변수 ga

console.log(ga);//Global variable 출력
console.log(window.ga);//브라우저에서 실행시 Global variable 출력

/**
 * 글로벌 영역에 선언한 함수는 전역객체(window)의 프라퍼티로 접근할 수 있는 전역 객체의 메서드임
 */
function foo() {
  console.log('invoked!');
}
window.foo();//브라우저에서 실행시 invoked! 출력(foo는 글로벌 영역에서 선언되었으므로 전역객체의 메서드이다)

----------------------------------------------------------------------------------------------------------------

프로토타입 객체도 메소드를 가질 수 있다. 프로토타입 객체 메소드 내부에서 사용된 this도 일반 메소드 방식과 마찬가지로 해당 메소드를 호출한 객체에 바인딩된다.(즉 해당 메서드(getName)는 해당 객체에 없고 prototype객체에 있는 메서드지만 그 메서드안에 쓰인 this는 메서드를 호출한 me객체에 바인딩된다.)

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());