반응형
250x250
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

this(this는 호출 시 결정) 본문

JS/인간 JS엔진

this(this는 호출 시 결정)

5_hyun 2024. 1. 23. 00:53

JS의 this는 다른 언어와 좀 다르다.

console.log(this)를 하면 window가 나온다.

기본적으로 this는 window라고 생각하면된다.

 

-함수

function a() {    
    console.log(this);
}
a();

함수에서도 this는 window가 나온다.

globalThis

JS에서는 window, Node에서는 global

=> 최근 스팩에서는 globalThis로 합쳐짐

window의 2가지 역할

  1. 브라우저 안의 모든 요소들이 소속된 객체로, 최상위에 있기에 어디서든 접근이 가능해서 '전역 객체'라고도 부른다.
  2. 일반적으로 우리가 열고 있는 브라우저의 창을 의미하고, 이 창을 제어하는 다양한 메서드를 제공한다. 
    • ex) window.innerWidth, window.innerHeight 등

'use strict' 모드

function a() {    
    'use strict'
    console.log(this);
}
a();

strict 모드에서는 this가 undefined가 나와야 한다.

 

this가 변하는 경우

-예시1

const obj = {
    name: 'zerocho',
    sayName() {
        console.log(this.name);
    }
};

obj.sayName();

여기서 this는 obj

 

-예시2

const obj = {
    name: 'zerocho',
    sayName() {
        console.log(this.name);
    }
};

const sayN = obj.sayName;
sayN();

여기서 this는 window

 

-예시3(화살표 함수)

const obj = {
    name: 'zerocho',
    sayName: () => {
        console.log(this.name);
    }
};

obj.sayName();

여기서 this는 window

화살표 함수인지 아닌지도 this를 결정하는데 큰 역할을 함

 

-예시4(new)

 

-예시5

  • bind는 새로운 함수를 만드는 것
  • apply, call은 새로운 함수를 만들고 호출까지 해주는 것
  • a.apply(window) === a.bind(window)() === a.call(window)

-apply, call의 차이점

function add(a, b) { return a+b }

add.apply(null, [3,5]);
add.call(null, 3, 5);
  • add에서 this를 사용하지 않기에 apply, call 둘 다 this 자리에 null을 넣어도 됨
  • apply는 인자를 배열로 넣고
  • call은 인자를 그냥 값으로 넣음

✅여기서 중요한 점

const obj = {
    name: 'zerocho',
    sayName() {
        console.log(this.name); // 이 부분 this
    }
};

위 코드의 this는 항상 obj인게 아니다

 

-this 결정 규칙

  • 가장 기본적으로 this는 window
  • 바뀌는 경우
    • obj.sayName()처럼 함수 앞에 객체가 붙으면 this가 앞의 객체(obj)가 됨
    • new를 사용하는 경우
    • bind, apply, call로 this를 바꿔주는 경우
    • 화살표 함수에서는 부모의 this를 물려받음(이때 부모가 어떻게 호출되었는지에 따라 또 달라짐)

어떻게 판단할까?

=> 렉시컬 스코프처럼 코드 작성 시 정해지는 것이 아니라, this는 함수가 호출될 때 정해진다.

문제

(1) console.log의 결과는?

const obj = {
    name: 'zerocho',
    sayName () {
        console.log(this.name);
        function inner() {
            console.log(this.name);
        }
        inner();
    }
};

obj.sayName();
더보기

결국 inner() 안의 console.log의 this는 window이다.

 

-이유

  • obj.sayName()에서는 obj가 앞에 붙었고, sayName이 화살표 함수가 아니기 때문에 'zerocho'가 출력
  • inner()는 함수 호출 시, this를 바꾸는 행동을 아무것도 안해서 window가 됐다.
    => 결국 this는 호출 시 결정된다!!

 

(2) console.log의 결과는?

const obj = {
    name: 'zerocho',
    sayName () {
        console.log(this.name);
        const inner = () => {
            console.log(this.name);
        }
        inner();
    }
};

obj.sayName();
더보기

둘 다 sayName이 된다.

 

-이유

  • inner() 안의 this가 바뀐 것을 보려면, 우선 함수가 호출될 때를 보면된다.
    • 일단 inner();에서는 this를 바꿔주는 행동을 안했다.
  • 화살표 함수는 부모 함수의 this를 가져온다.
    • 여기서 inner()의 console.log의 this는 obj.sayName()이 실행됨으로써 실행되었다.
    • 따라서 sayName의 this가 적용된다.

 

그렇기에 이 부분만 보고 this를 물어보면, this는 모른다고 답해야 한다.
this는 호출 시에 결정되기 때문이다! 

(3) console.log의 결과는?

const obj = {
    name: 'zerocho',
    sayName () {
        console.log(this.name);
        const inner = () => {
            console.log(this.name);
        }
        inner();
    }
};

const sayN = obj.sayName;
sayN();
더보기

둘 다 this는 window가 된다.

 

-이유

  • sayN에 담았다가 꺼낼 때 this를 바꿔주는 행동을 하지 않았기 때문이다.
  • 결국 그냥 함수로 호출하면 무조건 this는 window다.

분석

호출 스택 분석1(strict 모드가 아닐 때)

 

  1. 처음엔 anonymous가 호출 스택에 쌓이고, this = window
  2. obj.sayName이 호출 스택에 쌓이고, obj 객체가 앞에 있기에 this = obj
  3. console.log를 하여 첫번째 'zerocho' 출력
  4. inner가 호출 스택에 쌓이고, 화살표 함수라 부모의 this를 받아서 this = obj
  5. console.log를 하여 두번째 'zerocho' 출력

호출 스택 분석2(strict 모드가 아닐 때) 

  1. 처음엔 anonymous가 호출 스택에 쌓이고, this = window
  2. obj.sayName이 호출 스택에 쌓이고, obj 객체가 앞에 있기에 this = obj
  3. console.log를 하여 첫번째 'zerocho' 출력
  4. inner가 호출 스택에 쌓이고, inner()는 그냥 함수고 화살표 함수도 아니라 this = window
  5. console.log를 하여 window의 name ''출력

-출처

https://www.youtube.com/watch?v=pgo6URFz8tc&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=7

 

728x90
반응형

'JS > 인간 JS엔진' 카테고리의 다른 글

블록 스코프와 매개변수  (0) 2024.01.24
this를 분석할 수 없는 케이스  (0) 2024.01.23
호이스팅  (0) 2024.01.21
스코프 체인  (0) 2024.01.21
호출 스택 분석  (0) 2024.01.20
Comments