Front-End

[Vue.js] (arrow function)화살표 함수()=> 사용시 this는 Window객체를 바인딩한다, Vue 인스턴스가 아니다.

Vue.js에서 화살표 함수(arrow function) 사용과 일반 함수 사용 방법은 매우 간단하지만 애로우 함수를 사용하는 경우 표현방식이 햇갈리는 경우가 발생하여 공부를 하게되었다. 그러면서 우연히 computed() 에서 화살표함수를 구현하였는데 동작하지 않는다는 스택오버플로의 글을 발견하였다. 아래 스니펫과 같은 방식으로 화살표 함수를 사용하면 문제가 발생합니다. 

computed:{
    switchRed: () => {
        return {red: this.turnRed}
    },
    switchGreen: () => {
        return {green: this.turnGreen}
    },
    switchBlue: () => {
        return {blue: this.turnBlue}
    }
}

function 키워드를 생략해서 사용하는 방법은 가능합니다.

  computed:{
      switchRed() {
          return {red: this.turnRed}
      },
      switchGreen() {
          return {green: this.turnGreen}
      },
      switchBlue() {
          return {blue: this.turnBlue}
      }
  },

 

정상적으로 동작하는 코드 스니펫은 아래와 같다.

[HTML]

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.js"></script>
<div id="app">
  <div class="demo" @click="turnRed = !turnRed" :class="switchRed">빨강</div>
  <div class="demo" @click="turnGreen = !turnGreen" :class="switchGreen">녹색</div>
  <div class="demo" @click="turnBlue = !turnBlue" :class="switchBlue">파랑</div>
</div>

[JS]

new Vue({
  el: "#app",
  data: {
    turnRed: false,
    turnGreen: false,
    turnBlue: false
  },
  computed:{
  	switchRed: function () {
    	return {red: this.turnRed}
    },
    switchGreen: function () {
    	return {green: this.turnGreen}
    },
    switchBlue: function () {
    	return {blue: this.turnBlue}
    }
  },
  methods: {

  }
})

[CSS]

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

div {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.demo{
  width: 50px;
  height: 50px;
  background-color: gray;
  display: inline-block;
  margin: 10px;
}
.red{
  background-color: red;
}
.green{
  background-color: green;
}
.blue{
  background-color: blue;
}

[실행결과]


Vue 공식 문서 사이트에 보면 화살표 함수는 this를 갖을 수 없기 때문에 화살표 함수 내에서 this를 사용하게 되면 이것은 다른 변수로 취급되며, 상위 객체(Window 객체)를 바인딩함으로 종종 다음과 같은 Uncaught TypeError 오류가 발생합니다. 화살표함수는 부모 컥텍스트(Window 객체)에 바인딩됨으로 Vue인스턴스가 아닙니다. 그럼으로 data에 접근할 수 없게 됩니다.

 

모든 라이프사이클 훅은 자동으로 this 컨텍스트가 인스턴스에 바인딩되어 있습니다.

그럼으로 data, computed 및 methods 속성에 접근할 수 있습니다.

절대로 화살표 함수를 사용해서 라이프사이클 메소드를 정의하면 안됩니다. (예: created: () => this.testMethod()).

그 이유는 화살표 함수가 부모 컨텍스트를 바인딩하기 때문입니다.

그럼으로 this는 Vue 컴포넌트 인스턴스가 아니며 this.testMethod()는 정의되지 않습니다(undefined).


[주의할점]

vue인스턴스 속성들이나 콜백에 화살표함수를 사용하면 안됩니다. 즉, computed(), methods() 등의 속성 내에서 선언하는 함수는 절대로 화살표 함수를 사용하면 안됩니다. 반드시 일반 함수 방식으로 작성해야합니다.  

 

[REFERENCE]

 

 

 

 

 

Leave a Reply

error: Content is protected !!