[TIL] 항해99 12일차

오늘 한 것


오늘 배운 것

Javascript 특징 및 개념

Javascript this 용법

this는 그냥 이름처럼 대명사니까 대충 쓰면 될 것 같은데, 컴퓨터 언어에서는 아니다.
특히 javascript에서는 다른 언어에서 사용되는 것처럼 클래스로부터 생성되는 인스턴스 중 현재 객체만을 가리키는 것이 아니라 추가로 알아두어야 한다.

그래서 this를 어떻게 사용하는지, 어떻게 가리킬 수 있는 것인지 알아보려고 한다.

this

this는 사용 시 호출한 방법에 따라 결정되는 것.

다음과 같은 순서로 알아보기로 한다.

1) 전역에서 사용하는 this
2) 함수에서 사용하는 this
3) this 호출 메서드
4) 화살표 함수(arrow function)에서 사용하는 this

1. 전역에서의 this

먼저 this를 사용하면서 엄격모드(strick mode)와 비엄격모드(non-strict mode)를 알아야 하며 그 모드에 따라 this가 디폴트로 정해지는 값 또한 달라진다.

  • 비엄격모드(non-strict mode) : this 는 항상 "객체"를 참조.
  • 엄격모드(strict mode) : this는 어떠한 값이든 될 수 있음. => 무슨 뜻???

<전역에서 사용한 this>

console.log(this === window) // true

a = 37
console.log(this.a) // 37 (window.a)

하지만, 위의 코드처럼 전역 실행 context라면 웹 브라우저에서는 window 객체가 전역 객체가 된다.(엄격/비엄격 모두)

따라서 저기서 this는 window 객체를 가리킨다!

2. 함수에서의 this

이제부터 함수를 호출한 방법에 의해 this가 결정된다.
1) 단순 호출
- this 호출 설정이 없는 경우

  • 비엄격모드
function f1() {
  return this
}

// 브라우저
f1() === window // true

비엄격모드에서 this 호출 설정이 없는 경우에는 this는 "객체"를 참조하므로 default로 window 객체가 된다.

  • 엄격모드
function f2() {
  "use strict" // 엄격 모드
  return this
}

f2() === undefined // true

엄격모드에서 this 호출 설정이 없는 경우에는 this는 f2의 context에 진입하며 설정되는 값을 유지하므로 default는 undefined가 된다. (window 아님)

그렇다면 this를 다른 것을 가리키도록 어떻게 하지?? 매개변수를 주면 this가 호출될까?

console.log(f2("define")) // undefined

단순히 매개변수에 어떤 것을 넣어서 전달을 했음에도 똑같이 undefined가 나온다..

그럼 어떻게 다른 context에서 저 f2 context에 있는 this값을 호출할 수 있을까?

그래서 바로 call, apply, bind 메서드가 필요한 것이다!

2) 메서드를 활용한 호출
- call, apply, bind를 활용한 호출

<call / apply를 이용한 호출>

console.log(f2.call("defined")) // defined
console.log(f2.apply("defined")) // defined

함수에 call 혹은 apply를 붙이고 매개변수로 어떤 것을 전달하면 그것이 this가 되어 사용되게 된다. (f2 에서는 그냥 this 값이 반환)

call과 apply의 차이는 apply는 매개변수가 배열일 때 유용하다 (밑의 예시 코드 참조)

<bind를 이용한 호출>

const test = {
  prop: 42,
  func: function inTest() {
    return this.prop
  },
}

const another = {
  prop: 24,
}

// 그냥 호출
console.log(test.func()) // 42 (test.prop)
// bind로 this를 지정
let boundResult = test.func.bind(another) // this가 another가 된 inTest 함수를 반환
console.log(boundResult()) // 24 (another.prop)

bind로 this를 지정(another)하여 another.prop을 나타낸다.

위의 코드에서 another로 this가 정해졌으니, this는 계속 another가 된다.(다른 값을 가리키지 않는다.)

bind는 원본 함수를 가진 새로운 함수를 생성한다. 그 새 함수의 this는 호출 방식에 상관없이 무조건 bind의 첫번째 매개변수로 고정되는 것이다.
(=> bind를 사용하면 함수를 리턴해주고, 그 함수의 this 값을 영구히 설정한다.)

3. 화살표 함수에서의 this
화살표 함수에서 this는 자신을 감싼 정적 범위이다. 전역에 있다면 전역 객체를 가리키게 되는 것.

let globalObject = this // 전역이니까 window(브라우저에서)
let foo = () => this // 전역이니까 자신을 감싼 범위 => window
console.log(foo() === globalObject) // true

// 객체로서 메서드 호출
var obj = { func: foo }
console.log(obj.func() === globalObject) // true

// call을 사용한 this 설정 시도
console.log(foo.call(obj) === globalObject) // true

// bind를 사용한 this 설정 시도
foo = foo.bind(obj)
console.log(foo() === globalObject) // true

위 처럼 어떤 메소드를 사용해서 this 값을 호출하더라도 무시한다.



이해를 돕기 위한 코드의 예

  1. 일반 호출과 bind 메서드
let obj = {
  name: "anon",
  f: function thisF() {
    console.log(this + "되었습니다.")
    return "this is thisF"
  },
}

// 객체 안에 있는 함수 실행
let fSelf = obj.f() // { name: 'anon', f: [Function: thisF] }
console.log(fSelf) // this is thisF

// 함수에는 bind를 사용할 수 있다.
let fBind = obj.f.bind("bind")
// fBind는 함수가 되므로 실행하면
fBind() // this + 되었습니다 > bind되었습니다. 가 출력
  • 일반 호출 시, f함수를 실행하면 .앞에 있던 obj가 f의 함수 안에 있는 this가 됨
    그래서 this => obj 객체 자체가 출력된다.

그래서 fSelf는 obj.f()는 함수의 반환값을 반환받은 것이므로 string "this is thisF"가 출력된다.

  • bind 호출 시 매개변수는 아무거나, 그 매개변수가 무조건 this가 되므로 여기서는 "bind" string 값이 this가 된다.
    bind는 함수를 return해주므로 this가 "bind"인 thisF 함수가 fBind에 할당이 된다.
    따라서 fBind를 실행하면 this는 "bind"로 고정되어 있으므로 "bind 되었습니다"가 출력된다.
  1. 일반 호출과 call 메서드
const mike = {
  name: "mike",
}

function showThisName() {
  console.log(this.name) // 객체.name
}

// 이렇게 아무 매개변수 없이 호출하면
showThisName() // undefined
// this가 가리키는 것은 여기서 window 이므로 (비엄격모드)
// window.name은 정의되어 있지 않으니 undefined 출력.

// call 메서드로 호출
showThisName.call(mike) // mike
// mike 객체를 넘겨주어 this가 mike를 가리키게 하여 mike의 name. 즉, mike.name이 console에 찍히게 된다.

함수를 사용하면서 call을 하고 this로 사용할 객체를 넘기면 해당 함수(showThisName)가 주어진 객체(mike)의 메서드인 것처럼 사용할 수 있다.

  1. call / apply / bind 메서드
const mike = {
  name: "mike",
}

function update(birthYear, occupation) {
  this.birthYear = birthYear
  this.occupation = occupation
}

위의 객체와 this가 들어있는 함수에 call,apply,bind 메서드를 이용하여 mike 객체를 업데이트하는 방법

  • call
update.call(mike, 1999, "singer")
console.log(mike) // { name: 'mike', birthYear: 1999, occupation: 'singer' }

update를 call하여 첫번째 인자로 mike, 즉 this를 지정하고 나머지 객체를 전달해주니까
그 객체(mike)의 birthYear, ocuupation을 각각의 값으로 지정한다.

  • apply
    call과 거의 같지만, 매개변수를 배열로 받는다
update.apply(tom, [2002, "teacher"])
console.log(tom) // { name: 'tom', birthYear: 2002, occupation: 'teacher' }
  • bind
const updateMike = update.bind(mike)
updateMike(1980, "police")
console.log(mike) // { name: 'mike', birthYear: 1980, occupation: 'police' }

bind는 항상 mike를 this로 받음.
따라서, updateMike에 첫번째 인자로 굳이 mike 객체라고 명시해주지 않아도 this는 mike로 이미 영구히 지정되어있다.

<더 쉬운 call과 apply 예>
보통 Math.min 사용 시 spread 연산자로 사용

const nums = [3, 10, 1, 6, 4]
const minNum = Math.min(...nums) // 1
const maxNum = Math.max(...nums) // 10

call로도 spread 연산자로 요소를 차례대로 전달

const anotherMax = Math.max.call(null, ...nums) // 10
// Math.min.call(null, 3, 10, 1, 6, 4)

하지만 apply 사용하면 이렇게도 가능
두번째 요소를 배열로 전달하면 요소들을 차례대로 인수로 사용.
첫번째 요소는 무엇을 넣어도 상관없다.

const anotherMin = Math.min.apply(null, nums) // 1
// Math.min.apply(null, [3, 10, 1, 6, 4]) 

아직 this에 관한 내용은 더 많고, 빠뜨린 내용도 있다. 생성자로서의 this, 객체의 프로토타입 체인에서의 this 등..
일단은 용법이 어느 정도인지는 알았으니 사용해보거나 다시 이 구문을 만났을 때 모르는 것이 있으면 다시 찾아보는 식으로 공부해야겠다.

추가로 계속 공부하다보니 실행 컨텍스트, 렉시컬 컨텍스트 등 개념을 확실히 해야할 것들이 생긴다.ㅠㅠ

[참고 및 출처] https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
[참고 및 출처] https://www.youtube.com/watch?v=KfuyXQLFNW4&list=PLZKTXPmaJk8JZ2NAC538UzhY_UNqMdZB4&index=13

도커(Docker)

도커 - 어플리케이션을 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼

처음 산 노트북에는 아무것도 안 깔려있을 터,
버전을 맞추기도 해야하고 툴도 깔아야 개발이 가능해지기도 하고
또 서버를 구축했는데 더 좋은 서버로 옮기려면 설정을 또 해야한다는 것.
=> 그래서 도커를 쓴다.

도커는 각 요소들이 설치된 모습을 이미지란 형태로 박제해서 저장.
(공식적인 이미지도 있고, 원하는 대로 만들어 낼 수도 있음)

dockerhub란 곳에 이런 것들이 업로드돼서 공유되고 다운받을 수 있다.
그 일련의 설치과정들을 어디서든 컴퓨터가 자동으로 재현할 수 있도록 녹화떠둔 것 마냥 된다는 것.

  • 원시타입 / 객체타입

좋은 웹페이지 즐겨찾기