This

Taehun Jeong·2023년 2월 15일
1
post-thumbnail

Javascript

This in JavaScript

JavaScript에서의 this는 선언된 시점에 따라 달라진다. 사전적인 의미로는 현재 실행중인 함수가 속한 객체, 또는 자신이 생성할 인스턴스를 나타낸다. 따라서 함수를 호출한 시점에 this가 결정된다고 볼 수 있다.
this는 다음의 특징을 갖는다고 할 수 있다.

  1. this는 모든 곳에 존재한다.
  2. 함수 안의 this는 어떻게 함수를 부르는가에 달렸다.
  3. 화살표 함수 안의 this는 선언될 때 결정된다.

1.this는 모든 곳에 존재한다.

this
실행 결과

콘솔 창에서 this를 입력했을 때에 window가 반환되는 것은 함수 밖의 전역 실행 문맥에서 this를 호출했기 때문에 현재 코드가 실행중인 javascript의 런타임, 브라우저를 반환한 것이다.

function foo(){
    this.name="FOO";
    return this;
}

const bar=new foo();
bar
실행 결과

new 연산자를 사용하여 생성자 함수방식으로 인스턴스를 생성한 경우, this는 new로 만들어진 빈 객체를 가리키게 된다.

2.함수 안의 this는 어떻게 함수를 부르는가에 달렸다.

function foo(){
    console.log(this);
}
실행 결과

foo라는 함수를 만들어 실행시키면 foo()는 전역에서 실행되는 것이므로 실행 중인 현재의 인스턴스인 window를 가리킨다. 하지만

const greet={
	name:"Hoonystory",
    hello(){
      	console.log(this);
    	console.log("Hello, "+this.name);
    }
}

greet.hello();
실행 결과

위의 코드에서는 hello 메서드를 호출했을 때, this.name은 현재 greet 객체 내의 hello를 실행 중이므로 console.log(this)를 실행시켰을 때의 현재 객체인 greet를 반환하고 this.name을 호출하면 greet의 name을 반환한다.

const baz={
    nums: [1,2,3,4,5],
    readNums() {
        this.nums.forEach(function(num) {
            console.log(num);
            console.log(this);
        });
    }
}

baz.readNums();
실행 결과

객체 내의 메서드를 통해 실행된 고차함수의 경우 각 매개변수마다 콜백 함수를 실행해주며, 콜백 함수는 일반 함수이므로 this를 호출했을 때 window를 반환한다.

const baz={
    nums: [1,2,3,4,5],
    readNums() {
        this.nums.forEach(function(num) {
            console.log(num);
            console.log(this);
        },this);
    }
}

baz.readNums();
실행 결과

콜백 함수 다음의 참조할 인자로 객체를 전달해주면 this를 호출했을 때, 참조하는 객체를 반환한다.

this의 바인딩

this가 특정한 대상을 가리키도록 하는 것을 바인딩이라고 한다. 바인딩으로 사용하는 함수는 call, apply, bind가 있다.

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

const obj={
	name: "honystory",
}

foo.call(obj);
실행 결과

foo는 this를 출력하는 함수로 일반적으로 실행할 경우, 전역에서 실행되어 window를 반환할 것이다. function.call을 통해 this를 지정해주면 foo.call(obj)를 실행했을 때, foo는 지정된 this인 obj를 출력한다.

function foo(a, b){
    this.num = this.num + a + b;
    console.log(this.num);
}

const obj={
    num: 5,
}

foo.apply(obj,[1,2]);
실행 결과

apply는 call과 기능적으로 동일하나, 인자를 전달받을 때, call은 각각의 인자를 개별로 전달받지만 apply는 array 하나를 받는다.

3.화살표 함수 안의 this는 선언될 때 결정된다.

const foo={
    list: ["a","b"],
    getList(){
        setTimeout(function(){
            console.log(this.list);
        },2000);
    }
}

foo.getList();
실행 결과

위의 코드는 2초 뒤 foo의 getList를 실행하는 함수이다. 객체인 foo안에서 실행되기 때문에 this.list를 호출하면 ["a","b"]를 반환해야 하지만 undefined를 반환한다. setTimeout은 비동기 함수이므로 getList가 결과를 반환할 당시의 this는 window가 되기 때문이다.

const foo={
    list: ["a","b"],
    getList(){
        setTimeout(() => {
            console.log(this.list);
        },2000);
    }
}

foo.getList();
실행 결과

화살표 함수를 통해 선언할 경우, this는 선언된 시점의 객체를 가리킨다. 위 함수를 실행하면 원래의 의도대로 2초 뒤, foo의 list를 반환한다. 이는 화살표 함수는 자신의 this를 가질 수 없기 때문에 자신의 상위의 렉시컬 범위(lexical scope)에서 this를 검색해서 사용하기 때문이다.

References

profile
안녕하세요

0개의 댓글