🔗 이어서... 함수 더 알아보기

📖 Timemer Function

타이머 전역함수

  • setTimeout(함수, 시간)
    : 일정 시간 후 함수 실행
  • setInterval(함수, 시간)
    : 시간 간격마다 함수 실행
  • clearTimeout( )
    : 설정된 Timeout 함수를 종료
  • clearInterval( )
    : 설정된 Interval 함수를 종료
// setTimeout() & clearTimeout() 사용해보기

setTimeout(() => {
  console.log("sumin")
}, 3000) 
// 3초 뒤에 콘솔 출력

const h1El = document.querySelector("h1")
h1El.addEventListener("click", () => {
  clearTimeout(timer)
}) 
// h1태그 클릭 시 3초뒤 함수 실행

📖 Callback Function

📌 함수의 인수로 사용되는 함수
특정한 실행 위치를 보장해주는 용도로 콜백 함수를 활용한다.

function timeout(callback) {
  setTimeout(() => {
    console.log("sumin")
    callback()
  }, 3000)
}
timeout(() => {
  console.log("done!")
})

timeout( ) 함수의 인수로 "done!"을 출력하는 코드를 넣으면 콜백함수가 된다.
이렇게 만들어진 콜백함수가 callback의 매개변수로 들어간다.

📖 생성자 함수와 클래스

const sumin = {
  firstName: "sumin",
  lastName: "kim", 
  getFullName: function () {
    return `${this.firstName} ${this.lastName}`
  },
}

function User(first, last) {
  this.firstName = first
  this.lastName = last
}

// prototype 메소드로 호출
User.prototype.getFullName = function () { 
  return `${this.firstName} ${this.lastName}`
}

// 새로운 객체 생성
const mango = new User("mango", "yoon")
console.log(mango.getFullName()) 
// 한번만 만들어져있는 getFullName()함수를 참조하여 mango yoon 출력

new 키워드를 통해 만들어진 함수(user)를 생성자 함수라 한다.
= 객체 데이터를 생성하는 함수

User와 같이 new키워드로 생성된 함수는 파스칼케이스로 입력한다.

생성자함수로 실행한 결과를 반환해서 할당된 변수( mango )를 생성자 함수의 instance라 한다.

user함수 prototype 속성 부분에 getFullName을 할당해주면 몇개의 객체를 생성하던 메모리에는 딱 한번만 만들어진다. 즉, new 키워드를 통해 생성자 함수와 instance를 만들고 prototype 속성을 통해 하나의 메모리 공간을 만든다. 그렇기때문에 자바스크립트는 prototype 기반의 프로그래밍 언어라고도 부른다.

상당히 복잡해보이는 생성자함수.. 생성자 함수를 더 깔끔하게 구현 할 수 있는 방법이 있다.

📖 위의 코드로 Class를 사용해보자!

class User {
  constructor(first, last) {
    // function 생략 가능
    this.firstName = first
    this.lastName = last
  }
  getFullName() { 
    return `${this.firstName} ${this.lastName}`
  }
}

const sumin = new User("sumin", "kim")
const mango = new User("mango", "yoon")

console.log(sumin) // User {firstName: 'sumin', lastName: 'kim'}
console.log(mango.getFullName()) // mango yoon

class 내부에는 constructor생성자가 존재해야 한다. 생성자는 클래스의 instance인 객체를 생성할 때 초기화를 담당하는 코드 블록이다. 클래스의 상속관계에서 초기화를 수행할 수 있도록 부모 클래스의 생성자를 호출하는 특징이 있다. 그렇기때문에 생성자 내부에는 return이 존재하지 않는다. new키워드를 통해 생성자함수가 명시적으로 호출되고 그것이 새로운 객체에 할당한다. class키워드를 사용하여 기존보다 깔끔한 문법을 구현 할 수 있다.

📖 함수 내부에 지정된 this

this 가 정의된 함수에서 일반함수는 호출 위치에 따라 this를 정의하고, 화살표함수는 자신이 선언된 함수 범위에서 this를 정의한다. this가 정의되지 않은 함수에서는 상관없다.

처음 들으면 이게 무슨말이지 싶을거다.......

const sumin = {
  name: "sumin",
  // 일반함수
  normal: function () { 
    console.log(this.name)
  },
  // 화살표함수
  arrow: () => { 
    console.log(this.name)
  },
}
  • sumin.normal( )
    메소드를 호출하면 sumin객체 내부에 위치하기때문에 그 객체가 곧 this가 된다. 즉, 호출 위치에서 정의된다.

  • sumin.arrow()
    메소드 호출 위치와 전혀 상관 없이 this가 선언된 함수 범위에서 정의되어 undifined를 출력한다. 즉, 화살표함수가 만들어지는 위치에서 this가 정의된다.

📌 일반함수에서의 this 예시

const timer = {
  name: "sumin!",
  timeout: function () {
    setTimeout(function () {
      console.log(this.name)
    }, 3000)
  },
}
timer.timeout()

위의 로직에서 this를 호출한 위치는 timeout()함수이다. 그러나 현재 thissetTimeout()함수를 정의하고있어 출력되지 않는다.

📌 화살표함수에서의 this 예시

const timer = {
  name: "sumin!",
  timeout: function () {
    setTimeout(() => {
      console.log(this.name)
    }, 3000)
  },
}
timer.timeout()

this가 정의된 위치는 timeout()함수 내부의 setTimeout()함수 내부에 위치한다. 즉, 함수 범위는 timeout()함수가 되고 this는 일반함수가 정의된 timer 객체를 가르키기때문에 this는 결국 timer가 된다.

상황에 따라 잘 사용하기!!

📖 "this" of JavaScript

그렇다면 this는 과연 무엇일까!!!!! 왜 이렇게 혼란스럽게 하는 것일까....
실행 컨텍스트(맥락)를 지원하는 자바스크립트의 키워드 this는 기본적으로 선언된 위치에 따라 값이 달라진다.

📌 첫번째 ) this는 항상 객체를 바라본다. this = 객체

this 상황에따라 참조하는 객체가 달라진다. 전역공간에 있을 때의 this는 window를 바라본다. 그러면this === window가 된다. 그렇다면 window.eventHandlerthis.eventHandler로 되는 것 일까?
아니다 !
코드는 기본적으로 명시적으로 쓰이는걸 선호한다. 에러와 버그와 모든 리스크를 생각해서 명시적으로 사용할 수 있을 땐 명시적으로 쓰자! 그래서 명시적이지 않은 this가 어려운 것이라고 한다..

📌 두번째 ) 실행 맥락( excute context=실행맥락 )으로 this를 연결한다.

let obj = {
  id: 1,
  getId: function(){
    return this.id
  }
}
console.log(obj,id) // 1
console.log(obj.getId()) // 1
console.log(this.id) // undefined

this는 getId( )메소드의 소유객체인 obj를 가르키고있다. 실행에서의 맥락으로 this를 연결하여 값이 출력되지만 메소드 내부의 this.id의 값은 정해져있지 않다.

📌 세번째 ) 실행시 소유자 확인이 안되면 this는 전역객체에 연결된다.

function caller(fn) {
  console.log(fn()) // undefined 
}

let obj = {
  id: 1,
  getId: function(){
    return this.id
  }
}

caller(obj.getId)

값이 undefined로 나온 이유는 호출이 실행되는 순간에는 소유자(obj)가 사라진다. 즉 this는 소유자인 obj에 연결되어있고 연결된 obj가 함수의 fn으로 들어가면 this의 실행은 obj까지가 된다.

profile
성장하는 과정에서 성취감을 통해 희열을 느낍니다⚡️

0개의 댓글

Powered by GraphCDN, the GraphQL CDN