JavaScript

[JavaScript] this에 대해 알아보자!

chief 2022. 6. 21. 21:34
반응형

🚀  들어가며...

  • 자바스크립트에는 this라는 키워드가 있습니다. this는 문맥에 따라서 다양한 값을 가지는 데, this가 쓰이는 함수를 어떤 방식으로 실행하느냐에 따라서 그 역할이 구별됩니다. this의 값들은 크게 4가지 정도로 나눌 수 있는데, this를 이용하는 함수를 4가지 방식 중에서 어떤 방식으로 실행하느냐에 따라 this의 값이 결정됩니다. 이러한 특성 때문에 this가 무엇을 지칭하는지 알기 위해서는 this가 사용된 함수가 어디서 어떻게 실행되었는지를 알아야 합니다.

 

📑 내용

JS에서 this의 할당은?

JS에서 this는 정적으로 할당 되지 않고, 동적으로 할당됩니다.

쉽게 말하자면, this가 선언되었을 때가 아닌, 호출되었을 때 결정된다는 의미입니다.

ex)

const person = function (name) {
    this.name = name;   // 이 때 this가 결정되는 것이 아니라
}

const person1 = new person('son');  // 이 때 결정 됩니다.
console.log(person1.name);     

 

JS에서 호출에 따른 this의 해석

1. 함수 호출

  • 일반적으로 일반 함수에서 this는 전역 객체(window)를 가르킵니다.
  • 모든 내부함수(함수속에 함수, 메소드 속 함수)의 this는 전역 객체(window)를 가르킵니다.
  • 콜백함수로 일반함수가 올 경우 전역객체(window)를 가르킵니다.

ex1)

var value = 1;

var obj = {
  value: 100,
  foo: function() {
    console.log("foo's this: ",  this);  // obj
    console.log("foo's this.value: ",  this.value); // 100
    function bar() {
      console.log("bar's this: ",  this); // window
      console.log("bar's this.value: ", this.value); // 1
    }
    bar();
  }
};

obj.foo();

ex2)

var value = 1;

var obj = {
  value: 100,
  foo: function() {
    setTimeout(function() {
      console.log("callback's this: ",  this);  // window
      console.log("callback's this.value: ",  this.value); // 1
    }, 100);
  }
};

obj.foo();

위 예제들을 보시면 이해가 가실겁니다.

2. 메소드 호출

  • 함수가 객체의 프로퍼티 값이면, 메소드로서 호출됩니다. 이 때, this는 메소드를 소유한 객체가 됩니다.
  • 프로토타입 객체도 메소드를 가질 수 있습니다. 그리고 프로토타입 객체의 this도 해당 메소드를 호출한 객체를 바인딩합니다.

ex1)

var obj1 = {
  name: 'Lee',
  sayName: function() {
    console.log(this.name);
  }
}

var obj2 = {
  name: 'Kim'
}

obj2.sayName = obj1.sayName;

obj1.sayName();   // /Lee
obj2.sayName();  // kim

ex2)

function Person(name) {
  this.name = name;
}

Person.prototype.getName = function() {
  return this.name;
}

var me = new Person('Cho');
console.log(me.getName());     // Cho

Person.prototype.name = 'Son';
console.log(Person.prototype.getName());    // Son

3. 생성자 함수 호출

  • 생성자 함수란 어떤 공통 성질을 가지는 객체들을 생성하는데 사용하는 함수입니다.
    생성자를 클래스(class), 클래스를 통해 만든 객체를 인스턴스(instance)라고 합니다.
  • JS는 함수에 생성자로서의 역할을 함께 부여 했습니다.
    new 명령어를 통해 함수를 호출하면 함수가 생성자로 동작하여 인스턴스 객체를 만듭니다. 이때 내부에서의 this는 새로 만들어진 인스턴스 자신이 됩니다.
  • 생성자 함수를 호출하면
    1. 생성자의 prototype 프로퍼티를 참조하는 __proto__ 라는 프로퍼티가 있는 객체를 생성합니다.
    2. 미리 준비된 공통 속성 및 개성을 해당 객체(this)에 부여합니다. 
  • new 명령어를 통해 함수를 호출하면 함수가 생성자로 동작하여 인스턴스 객체를 만듭니다. 이때 내부에서의 this는 새로 만들어진 인스턴스 자신이 됩니다.
// 생성자 함수
function Person(name) {
  this.name = name;
}

var me = new Person('Lee');
console.log(me); // {name: "Lee"}

// new 연산자와 함께 생성자 함수를 호출하지 않으면 생성자 함수로 동작하지 않습니다.
var you = Person('Kim');
console.log(you); // undefined

3-1 생성자 함수 동작 방식

  • 생성자 함수가 실행되기 전 빈 객체를 생성하고, 생성자 함수 내에서 사용되는 this는 이 객체를 가르킵니다. 빈 객체는 생성자 함수의 prototype 프로퍼티가 가르키는 객체를 자신의 프로토타입 객체로 설정합니다.
  • this를 통해 this가 가르키는 객체에 프로퍼티를 생성할 수 있습니다.
  • 생성자 함수의 return이 없는 경우 새롭게 바인딩 된 객체(this가 가르키는 객체)가 반환됩니다.
function Person(name) {
  // 생성자 함수 코드 실행 전 -------- 1번
  this.name = name;  // --------- 2번
  // 생성된 함수 반환 -------------- 3번
}

var me = new Person('Lee');
console.log(me.name);

3-2 객체 리터럴 방식과 생성자 함수 방식의 차이

const object = {
	name: "park",
	age: 12,
}  // 객체 리터럴방식

const Person = function (name, age) {
	this.name = name;
	this.age = age;
}  // 생성자 함수 선언

const person1 = new Person("Lee", 13);  // 생성자 함수 방식

위 객체 리터럴 방식과 생성자 함수 방식의 차이는 생성자 함수의 prototype 객체는 Object이고,

객체리터럴방식의 prototype 객체는 Person입니다.

3-3 생성자 함수에 new 키워드를 쓰지 않는 경우

  • 일반함수와 생성자 함수는 차이가 없습니다.

대부분의 new 없이 사용하는 빌트인 생성자(Array, Regex 등)는 scope-safe Constructor Pattern을 사용합니다. 아래는 scope-safe Constructor Pattern 의 예제입니다.

function A(arg) {

   // arguments.callee는 호출된 함수의 이름을 나타냅니다.
   if(!(this instanceof arguments.callee)) {
      return new arguments.callee(arg);
   }

   this.value = arg ? arg : 0;
}

var a = new A(100);
var b = A(100);

console.log(a.value);
console.log(b.value);

callee는 arguments 객체의 프로퍼티로서 함수 바디 내에서 현재 실행 중인 함수를 참조할 때 사용합니다. 즉, 함수 바디 내에서 현재 실행 중인 함수의 이름을 반환합니다.

 

🙋🏻‍♂️ 후기

this는 프론트개발자라면 익숙한 문법일텐데, 이렇게 자세히 살펴보면 많은 호출방법에 따라 다르게 쓰이는 것을 알 수 있습니다. 한번 짚고 넘어간다면, 추후에 this문법때문에 오류가 나와도 금방 알아차리실수 있을 것 같습니다. 제가 게시한 방법 이외에도 다르게 쓰이는 this를 좀더 확인하고 공부해야겠습니다.

 

🔗  참고한 글

https://velog.io/@cyheum/JavaScript-%EC%A0%95%EB%B3%B5%EA%B8%B0-%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-1

 

[JavaScript 정복기] this가 뭐야?? (코어 자바스크립트) - 1

javascript를 공부해보며 뭔가 깊이 몰랐던 부분들 위주로 정리 해보고자 한다.

velog.io

 

반응형