JavaScript의 this

eeensu·2023년 8월 18일
0

javascript

목록 보기
6/31
post-thumbnail

this

java와 C# 등의 객체지향 언어에서의 this는 현재 객체나 인스턴스 자신을 나타낸다. 이들은 객체 내에서 this를 씀으로써 자신의 인스턴스 변수나 함수에 접근을 할 수 있다.

하지만 js에서의 this는 다른 언어들과는 다른 특징을 갖고 있다. js에서의 this에는 반드시 자기 자신의 객체가 무조건 들어가지는 않는다. 함수를 호출하는 방식에 따라 동적으로 this가 지칭하는 객체가 달라진다.

즉, js의 this는 함수가 호출되는 시점의 실행 컨텍스트(Execution Context)이며 함수를 실행하는 환경(호출하는 방법, 환경)이 달라지면 this도 변한다는 것이다.



this가 가지는 여러 case

  • 전역
    전역에서의 this는 기본적으로 window 객체이다.
console.log(this)				// window
console.log(this === window)	// true

  • 일반 함수
    일반 함수에서의 this 는 strict 모드 지정에 따라 다른 값을 가진다.
// strict 모드가 아닐 경우
function whatIsThis() {
 	console.log(this);				//  window
}
// strict 모드일 경우
function whatIsThis() {
	console.log(this);				// undefined
}

  • 객체의 일반 함수
    객체안에 있는 일반 함수의 this 는 객체 자신을 가리킨다.
const user = {
  name: 'James',
  showName: function () {
    console.log(this.name);			// user.name
  },
  whatIsThis: function () {
    console.log(this);				// user 
  }
};

  • 생성자 함수의 호출
    생성자 함수를 사용하여 객체를 생성할 때, this는 생성된 인스턴스를 가리킨다.
function Person(name) {
  this.name = name;
}

const person1 = new Person('Alice');
console.log(person1.name);						 // Alice



이러한 this의 유연한 특징은, 개발하는 데 있어서 개발의 다형성을 구현하는 데 도음이 되었다. 하지만 동시에 혼란을 초래할 수 있다는 단점도 가지고 있기에, 이를 개선하기 위해서 ES는 여러 개선점을 추가하였다.

1. ES5

  • strict mode 도입
    strict mode에서는 this 사용을 보다 엄격하게 관리하여 오류를 미리 방지한다.

  • bind 메서드 도입
    함수의 this를 특정 객체에 바인딩하는 bind 메서드가 도입되어 명시적인 바인딩을 지원한다.


2. ES6 (ES2015)

  • 화살표 함수 (Arrow Function) () => {} 도입
    화살표 함수 내부에서 this는 함수를 둘러싼 스코프의 this와 같아지며, 외부에서 정의된 this 값을 그대로 사용한다. 즉, 객체의 메서드 정의를 function이 아닌 화살표 함수를 작성하면 this는 객체가 아닌 객체의 외부를 스코프한다.

  • 클래스 (class) 도입
    class 내부에서 메서드를 작성할 때, 그 메서드 내부의 this는 해당 클래스의 인스턴스를 가리킨다.




call, apply, bind

우리는 js의 함수를 작성할 때 마다 해당 함수가 가질 수 있는 함수인 call(), apply(), bind() 메서드를 보았을 것이다. 이 기능들은 해당 함수의 this 값을 명시적으로 설정하거나 바인딩하기 위한 메서드들이다. 이들은 함수의 호출 방식과 컨텍스트를 제어하며, this 가 지칭하는 바를 특정해준다.

  • call
    call 메서드는 함수를 즉시 호출하면서 특정 객체를 this로 지정하고, 함수의 인수를 개별적으로 전달하는 역할을 한다.
function greet(firstName, secondName) {
  console.log(`Your name is ${firstName} ${secondName}! My name is ${this.name}!`);
}

const person = { name: 'Jayce' };
greet.call(person, 'Bang', 'Junsu');				// Your name is Bang Eunsu! My name is Jayce! 

  • apply
    apply 메서드는 call과 유사하지만, 함수의 인수를 배열 형태로 전달한다.
function greet(firstName, secondName) {
  console.log(`Your name is ${firstName} ${secondName}! My name is ${this.name}!`);
}

const person = { name: 'Jayce' };
greet.apply(person, ['Bang', 'Junsu']);				// Your name is Bang Eunsu! My name is Jayce! 

  • bind
    bind 메서드는 call과 apply와 다르게 많은 차이점을 가지고 있다. 함수를 호출하지 않고 새로운 함수를 생성한다. 또한 초기 함수 호출 시 전달한 인수와 함께 새로운 함수가 생성되므로, 그 이후에 추가적인 인수를 전달하여도 적용되지 않는다.
function greet(name) {
  console.log(`Hello, ${name}! My name is ${this.name}.`);
}

const person = { name: 'Alice' };
const greetPerson = greet.bind(person);

greetPerson('Bob'); 			// Hello, Bob! My name is Alice.
profile
안녕하세요! 26살 프론트엔드 개발자입니다! (2024/03 ~)

0개의 댓글