Frontend/JS.info 정리

객체: 기본 - method 와 this

Creative_Lee 2021. 12. 19. 19:24

객체는 실존하는 개체를 표현하고자 할 때 사용합니다!

 

* 개체(entity)란?

현실 세계에서 조직을 운영하는 데 꼭 필요한 사람이나 사물과 같이 구별되는 모든 것을 의미한다. 

 

* 메서드(method)란?

객체의 프로퍼티에 함수를 할당할 수 있습니다.

객체 프로퍼티에 할당된 함수를 method 라고 부릅니다!

 

 

method 만들기

 

1. 객체 밖에서 함수 표현식으로 생성

let user = { 
  name : 'Lee',
  age : '26'
}

user.hi = function(){
  console.log(`hi! ${user.name}`)
}

user.hi(); // hi! Lee

 

2. 이미 정의된 함수를 사용해서 생성

let user = { 
  name : 'Lee',
  age : '26'
}

function hi(){
  console.log(`hi! hello!`)
}

user.hi = hi

user.hi() // hi! hello!

 

3. 객체 안에서 생성

let user = { 
  name : 'Lee',
  age : '26',
  hi : function (){
    console.log(`hi! hello!`)
  }
}

user.hi() // hi! hello!

 

4. 객체 안에서 메서드 단축 구문을 사용해서 생성

let user = { 
  name : 'Lee',
  age : '26',
  hi(){
    console.log(`hi! hello!`)
  }
}

user.hi() // hi! hello!

 

3번, 4번 방법은 완전히 동일하지 않습니다.

객체 상속과 관련된 미묘한 차이가 존재합니다. ( 이 부분은 추후에 제가 더 배우고 나서 추가 할게요 ! )

 

 

method 와 this

대부분의 메서드는 선언된 객체의 포로퍼티 값을 활용합니다.

이때 메서드 내부에서 this 키워드를 사용하여 객체에 접근할 수 있습니다.

 

1. this의 활용

let user = { 
  name : 'Lee',
  age : '26',
  hi(){
    console.log(`hi! ${this.name}!`)
  }
}

user.hi() // hi! Lee!

 

2. 외부변수를 참조했을 때의 문제점...

this를 사용하지 않고 외부변수를 참조해 객체 접근도 가능하지만....

let user = { 
  name : 'Lee',
  age : '26',
  hi(){
    console.log(`hi! ${user.name}!`)	// 외부변수 참조!
  }
}

let clone = user;  // 객체 shallow copy!

user = null;  // 원본 박살!

clone.hi() // TypeError: Cannot read properties of null
--> user.name을 참조하고 싶지만 user는 이미 박살났습니다.

 

2-1. this로 해결완료!

this로 바꾸면 해결됩니다!

let user = { 
  name : 'Lee',
  age : '26',
  hi(){
    console.log(`hi! ${this.name}!`)
  }
}

let clone = user;

user = null;

clone.hi() // hi! Lee!

--> this를 사용해 객체에 접근한 경우 원본이 터졌어도 메소드 실행이 가능합니다.

 

 

자유로운 this

자바스크립트에서는 모든 함수에 this를 사용할 수 있습니다. 

 

그래서 이런 코드를 작성해도 문법 에러가 발생하지 않습니다.

function hi (){
  console.log(`hi ${this.name}`)
}

문법적 오류는 없습니다.
아직은 this의 주인이 없습니다.

 

this의 값은 런타임에 결정됩니다.

같은 함수라도 호출하는 객체에 따라 this의 참조가 달라집니다 !!

function hi (){
  console.log(`hi ${this.name}`)
}

let user = {name: 'Lee'}
let player = {name: 'Player'}

user.hi = hi;	// 동일 함수 할당!
player.hi = hi;	// 동일 함수 할당!

user.hi()	// hi Lee 
player.hi()	// hi Player

같은 함수를 할당했지만 this가 참조하는 값은 각 객체이기 때문에 다른 결과값이 출력되었습니다.

 

객체 없이 호출하기

객체 없이 함수를 호출할 수 있습니다.

 

1. 엄격모드가 아닐 때!

function hi (){
  console.log(this)
}

hi() // Window{.....}

엄격모드가 아닐 때
this는 전역 객체를 참조합니다.( 브라우저 환경에서는 Window )

 

2. 엄격모드 일 때

'use strict'

function hi (){
  console.log(this)
}

hi()  //undefined

엄격모드 일 때
this는 undefined 입니다.

이 둘의 동작 차이가 "use strict" 가 도입된 배경이기도 합니다. ( 이 부분은 추후에 제가 더 배우고 나서 추가 할게요 ! )

 

보통의 경우 이런식의 코드는 실수로 작성된 경우입니다.

함수 본문에 사용된 this를 발견하면 다른 객체 내에서 함수를 호출할 것이라고 예상해도 되겠습니다!

 

다른 언어를 사용하다 자바스크립트를 배우는 개발자는 this 를 혼동하기 쉽습니다.

this 는 항상 매서드가 정의된 객체를 참조할 것이라고 착각하죠.

이러한 개념을 bound this 라고 합니다.

 

자바스크립트의 this는 런타임에 결정됩니다.

매서드의 정의 지점에 상관없이 this의 점 앞의 객체가 무엇인가에 따라 자유롭게 결정됩니다.

 

 

this가 없는 화살표 함수!

화살표 함수는 일반 함수와 다르게 고유한 this를 가지지 않습니다.

화살표 함수에서 this를 참조하면, 외부 함수에서 this값을 가져옵니다!

let user = {
  name : 'Lee',

  hi(){
    let phrase = ()=>{
      console.log(`hi ${this.name}`)  // 화살표함수의 this는 외부함수 hi()의 this입니다.
    }
    phrase();
  }
}

user.hi() // hi Lee

별개의 this를 만들기 싫고, 외부 컨텍스트의 this를 사용하고 싶을 경우에

화살표 함수를 사용하면 되겠습니다!

 

 

기본이 중요하다!