Programming/JavaScript & TypeScript

Javascript에서의 this

홍열 2022. 5. 24. 15:54
728x90

다음 코드에서 this는 gangwon객체가 아닌 다른걸 가르키게 된다. 

var gangwon = {
  resorts: ["Kirkwood","Squaw","Alpine","Heavenly","Northstar"],
  print: function(delay=1000) {
	setTimeout(function() {
	  console.log(this.resorts.join(","))
	}, delay)

  }
}

gangwon.print()

실제로 setTimeout안에서 this를 찍어보면 다음과 같은 결과를 보여준다.

따라서 this.resorts를 접근할 수 없는 것이다.

아래 소스를 보고 더 분석해보자 

//node에서 this
/*
	함수 밖에서 this는 exports를 의미, 외부에게 제공하기 위한 내장객체를 의미
	자바스크립트 파일이 하나의 모듈
*/
console.log(this) //{}
console.log(this === exports) // true

function test(){
	/*
		함수 안에서 this를 사용하면 global 객체를 의미
		node의 global 객체 ===> html의 window 객체와 동일, 결국 window의 메서드가 된다..함수는
		일반함수는 this를 변형시킨다...
	
	*/
	console.log(this) // object global
	console.log(this === global) //true
	
}

test()

const test2 = () => {
	/*
		Arrow Function에서 this는 exports이다.
		Arrow Function은 this를 변형시키지 않는다.
	*/
	console.log(this)
	console.log(this === global)
	console.log(this === exports)
}
test2()

html에서는 아래처럼 테스트가 가능하다. 

Main

 

해결방법은 간단하다. 

1) Arrow function을 사용하자

    var gangwon = {
      resorts: ["용평","평창","강촌","강릉","홍천"],
      print: function(delay=1000) {
		//arrow function에서는 bind가 필요가 없다. arrow function는 this를 왜곡시키지않는다.
        setTimeout(
          () => console.log(this.resorts.join(",")),
          delay
        )

      }
    }

    gangwon.print()

2) bind를 사용하자 

var tahoe = {
  resorts: ["용평","평창","강촌","강릉","홍천"],
  print: function(delay=1000) {
	  //익명함수가 접근시에 알수가 없다.....bind를 통해서 익명함수에서 this를 변형시켜준다.
	setTimeout(function() {
		console.log(this)
	  console.log(this.resorts.join(","))
	}.bind(this), delay)

  }
}

tahoe.print()