HyunJun 기술 블로그

This, bind, static, Closure 본문

JavaScript

This, bind, static, Closure

공부 좋아 2023. 7. 13. 09:13
728x90
반응형

1. This

  • 기본적으로 this는 자기 자신을 가리키는 키워드이다.

 

1) 전역 스코프

전역 스코프에서의 this는 전역 객체인 window 객체를 가리킨다.

<script>
  console.log(this);
</script>

2) 객체 this

객체 내의 this는 객체 자기 자신을 가리킨다.

<script>
  ({
    a: 1,
    checkThis() {
      console.log(this);
    },
  }).checkThis();
</script>

 

3) 인스턴스 this

클래스에서 this를 사용하고 클래스를 통해서 인스턴스를 만들었을 때의 인스턴스로 접근했을 때의 this는 클래스 그 자체가 아닌, 인스턴스를 가리킨다.

<script>
  class Test {
    checkThis() {
      console.log(this);
    }
    checkThisArrow = () => {
      console.log(this);
    };
  }

  const test = new Test();

  test.checkThis();
  test.checkThisArrow();
</script>

4) 프로토타입 this

기본적으로 클래스와 같이 동작하지만, 화살표 함수에 있어서의 차이가 좀 있다.

<script>
  function Test() {}

  Test.prototype.checkThis = function () {
    console.log(this);
  };

  Test.prototype.checkThisArrow = () => {
    console.log(this);
  };

  const test = new Test();

  test.checkThis();
  test.checkThisArrow();
</script>

화살표 함수의 경우 this가 인스턴스를 가리키는 게 아닌, window 즉 전역 객체를 가리키고 있다.

이것을 이해하려면 바인딩과 화살표 함수에서의 바인딩에 대해서 알아야 한다.

2. bind(binding)

  • 자바스크립트의 bind()는 함수를 호출할 때 사용할 this를 다른 객체로 바꿀 수 있게 해준다.
  test.checkThis();
  test.checkThis.bind(window)();

test.checkThis 함수의 this를 window로 바인딩하고, "()"로 바로 실행했더니 아래와 같이 window 객체가 나왔다.

이 bind() 함수는 원본은 변경 시키지 않는다.

 

즉 아래와 같이 사용할 수 있다.

  const person = {
    name: "홍길동",
    info() {
      console.log(`내 이름은 ${this.name}입니다.`);
    },
  };

  person.info();
  person.info.bind({ name: "John" })();

 

여기서 중요한 점은, 생성자 함수(클래스)를 통해서 인스턴스를 만들면 this는 자동적으로 생성자 함수(클래스)에서 인스턴스로 바인딩 시켜주지만, 화살표 함수의 경우 this를 바인딩 시켜주지 않고, this를 선언한 위치의 상위 스코프를 기준으로 this가 적용된다.

  class ClassThis {
    name;

    constructor(name) {
      this.name = name;
    }

    classThis = () => {
      // 이 this는 상위 스코프인 ClassThis를 가리키게 됨.
      console.log(this);
    };
  }

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

  PrototypeThis.prototype.prototypeThis = () => {
    // 이 this는 바인딩 자체가 안되므로 상위 스코프인 전역 스코프의 this, 즉 window 객체가 적용됨.
    console.log(this);
  };

  const classThis = new ClassThis("Class");
  const prototypeThis = new PrototypeThis("Prototype");

  classThis.classThis();
  prototypeThis.prototypeThis();

3. static

  • 정적인 프로퍼티, 메서드 등을 정의할 때 사용한다.
  • 인스턴스에서 접근하는 것이 아닌 클래스 이름 자체로 접근한다.
  • 즉, 인스턴스의 생성 유무 상관없이 클래스 자체의 고유한 성질에 대한 프로퍼티나 메서드를 정의할 때 사용한다.
  class Person {
    name;
    age;

    static eyes = 2;

    constructor(name, age) {
      this.name = name;
      this.age = age;
    }

    static showEyes = () => {
      console.log(this.eyes);
    };
  }

  console.log(Person.eyes);
  Person.showEyes();

  let person = new Person("John", 20);
  console.log(person);

static으로 사용하는 프로퍼티와 메서드를 정적 프로퍼티, 정적 메서드라고 부른다.

 

만약 프로토타입으로 구현한다면 아래처럼 할 수 있다.

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

  Person.eyes = 2;
  Person.showEyes = () => {
    console.log(Person.eyes);
  };

  console.log(Person.eyes);
  Person.showEyes();

  let person = new Person("John", 20);
  console.log(person);

4. Closure

클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경과의 조합을 뜻한다. 아래와 같은 코드를 확인해 보면, closure() 함수는 함수를 리턴하고 있고 함수는 a라는 변수를 리턴한다. 해당 함수를 받은 tempClosure 함수를 실행해 보면

  function closure() {
    let a = 1234;

    return () => {
      return a;
    };
  }

  const tempClosure = closure();
  console.log(tempClosure());

a에서 값만 리턴해서 1234를 리턴한 것 같지만,

tempClosure 함수를 dir로 찍어보면

console.dir(tempClosure);

클로저 스코프와, a라는 변수와 값이 보이는 것을 확인할 수 있다.

728x90
반응형
Comments