PDH 개발 공부

[JavaScript] this 본문

JavaScript

[JavaScript] this

IFBB 2021. 7. 8. 12:21

JavaScript this

  • this 는 현재 실행 문맥 이다

alert(this === window) // true, 호출자는 window

const caller = {
  f: function() {
    alert(this === window)
  },
}
caller.f() // false, 호출자는 caller 객체

  • alert 도 따지고 보면 window.alert() 이다
  • strict-mode 에서 전역 객체냐 일반 객체냐에 따라 함수 내부에 this의 결과가 다르다
  • 이 문제 또한 window 를 함수 호출 앞에 붙여주면 해결된다

function nonStrictMode() {
  return this
}

function strictMode() {
  'use strict'
  return this
}

console.log(nonStrictMode()) // window
console.log(strictMode()) // undefined
console.log(window.stricMode()) // 

생성자 함수 , 객체


unction NewObject(name, color) {
  this.name = name
  this.color = color
  this.isWindow = function() {
    return this === window
  }
}

const newObj = new NewObject('nana', 'yellow')
console.log(newObj.name) // nana
console.log(newObj.color) // yellow
console.log(newObj.isWindow()) // false

const newObj2 = new NewObject('didi', 'red')
console.log(newObj2.name) // didi
console.log(newObj2.color) // red
console.log(newObj2.isWindow()) // false
  • 생성자는 객체지향 this 와 같다
  • newObj, newObj2 는 생성자 함수로 만들어진 객체이지만 완전히 별도의 객체

생성자에 new가 없다면??

const withoutNew = NewObject('nana', 'yellow')
console.log(withoutNew.name) // error
console.log(withoutNew.color) // error
console.log(withoutNew.isWindow()) // error
  • new 키워드가 없으면 일반적인 함수 실행과 동일하게 동작 한다.
  • 즉 this 는 window 객체가 된다

일반 객체에서는??

const person = {
  name: 'john',
  age: 15000,
  nickname: 'man from earth',
  getName: function() {
    return this.name
  },
}
console.log(person.getName()) // john

const otherPerson = person
otherPerson.name = 'chris'
console.log(person.getName()) // chris
console.log(otherPerson.getName()) // chris
  • 생성자 함수와 크게 다르지 않다

bind,arrow,function

window으로 취급 될 때

function Family(firstName) {
  this.firstName = firstName
  const names = ['bill', 'mark', 'steve']
  names.map(function(lastName, index) {
    console.log(lastName + ' ' + this.firstName)
    console.log(this)
  })
}

const kims = new Family('kim')
// bill undefined
// window
// mark undefined
// window
// steve undefined
// window
  • map 메서드의 서브루틴을 호출될때 map 의 context(this)로 바인드 되지 않는다
  • 바인드 되지 않았다는 것은 실행 문맥이 전역이라는 것
  • (비엄격모드에서) 즉 서브루틴 내 this가 window 이다

비슷한 현상 1

const testObj = {
  outerFunc: function() {
    function innerFunc() {
      console.log(this) // window
    }
    innerFunc()
  },
}
testObj.outerFunc()
  • outerFunc 가 외부에서 실행 되면 this 는 testObj 이다
  • 하지만 outerFunc 내부에서 innerFunc를 호출할때는 바인드 되지 않았다
  • 즉 전역(window)에서 실행이 됨

window 함수안에 this 접근 하고 싶다면?

function Family(firstName) {
  this.firstName = firstName
  const names = ['bill', 'mark', 'steve']
  const that = this
  names.map(function(value, index) {
    console.log(value + ' ' + that.firstName)
  })
}
const kims = new Family('kim')
// bill kim
// mark kim
// steve kim
  • that을 선언하여 처리를 해주면 된다
  • 하지만 상수를 만들어주는건 귀찮다

window 함수안에 this 접근 하고 싶다면? 보안 1

function Family(firstName) {
  this.firstName = firstName
  const names = ['bill', 'mark', 'steve']
  names.map(
    function(value, index) {
      console.log(value + ' ' + this.firstName)
    }.bind(this)
  )
}
const kims = new Family('kim')
  • 이 문제를 해결 하기 위해 bind를 사용한다
  • that을 쓸때보다 깔끔해졌지만 .bind(this) 도 귀찮아짐.

window 함수안에 this 접근 하고 싶다면? 보안 2

function Family(firstName) {
  this.firstName = firstName
  const names = ['bill', 'mark', 'steve']

  names.map((value, index) => {
    console.log(value + ' ' + this.firstName)
  })
}
const kims = new Family('kim')
  • arrow function으로 해결

어떻게 변환 된건지 babel 사이트로 변환한 결과


'use strict'

function Family(firstName) {
  var _this = this

  this.firstName = firstName
  var names = ['bill', 'mark', 'steve']
  names.map(function(value, index) {
    console.log(value + ' ' + _this.firstName)
  })
}
var kims = new Family('kim')
  • 아까 that과 같아진다.

참고 : https://blueshw.github.io/2018/03/12/this/

'JavaScript' 카테고리의 다른 글

[JavaScript] 비동기 처리 2  (0) 2021.07.12
[JavaScript] 비동기 처리 1 (CallBack 함수에 대해)  (0) 2021.07.12
[Node.js]Ejs  (0) 2021.07.08
Ajax  (0) 2021.07.08
[JavaScript] DOM ,BOM  (1) 2021.07.01
Comments