탕구리's 블로그

javascript Call & Apply, Bind 본문

javascript

javascript Call & Apply, Bind

탕구리당 2018. 9. 13. 11:26
반응형




시작하기 전에


해당 블로그에 작성되는 글은 주인장의 지극히 주관적인 생각이 다수이며, 대부분의 지식은 구글링을 통해 얻고 있기 때문에 옳지않은 정보가 있습니다. 

잘못된 부분이나 수정해야 하는 부분이 있다면 과감히 덧글을 남겨주세요! 모르는게 많은 새싹입니다




오늘의 주제


오늘의 주제는 Call과 Apply 그리고 Bind 메소드 입니다. 비슷한 역할을 하는 세 가지 메서드에 대해 알아보고, 

차이점을 파악하도록 하겠습니다!




Call & Apply, Bind

자바스크립트에서는 개발자 임의로 this를 특정 값으로 설정해 줄 수 있는 방법이 존재합니다.

총 세가지의 방법이 있습니다.- call- apply- bind

1. call() 메소드

fun.call(thisArg[ , arg1 [, arg2 [, ...]] )

기본적으로 call() 메소드는 위와같이 사용하며, 첫번쨰 인자로는 this의 값, 두번째 인자부터는 함수에 전달될 파라메터가 들어갑니다.

예제를 따라가 보면서 각각의 차이점에 대해서 알아봅시다.

const dongsu { name: 'Dongsu' }
const minsu { name: 'Minsu' }

function hello () {
 return`Hello my name is ${this.name}!`
}

hello() // Hello my name is !
hello.call(dongsu) // Hello my name is Dongsu!
hello.call(minsu) // Hello my name is Minsu!


위의 예제를 바꿔봅시다.

새로운 예제를 통해 call() 메소드에 인자를 넣어주지 않으면 전역객체를 가리키는걸 알 수 있습니다.

function hello() {
return `Hello my name is ${this}`
}

hello.call() // Hello my name is [object Window]!

# 새로운 예제
const dongsu {
 name: 'dongsu',
 update: function (birthYear, occupation) {
   this.birthYear birthYear
   this.occupation occupation
}
}

# ---------------------------------------

function update birthYear, occupation ) {
 this.birthYear birthYear;
 this.occupation occupation;
}

update.call(dongsu, 1991, 'BackEnd')
// dongsu = { name: 'Dongsu', birthYear: '1991', occupation: 'Backend'}
update.call(minsu, 1989, 'FrontEnd')
// minsu = { name: 'Minsu', birthYear: '1989', occupation: 'Frontend'}


fun.call()은 thisArg의 메소드처럼 function을 사용할 수 있도록 하는 역할(?)입니다.

Es6에 추가된 Spread operator를 이용해서 call() 메소드를 사용할 수도 있습니다.

const optionDongsu [1991, 'BackEnd']

update.call(dongsu, ...optionDongsu)
// dongsu = { name: 'Dongsu', birthYear: '1991', occupation: 'Backend'}


2. apply() 메소드

fun.call(thisArg, [argsArray])

거의 모든 사용법이 call() 메소드와 동일하지만, 두번째 파라메터로 배열을 사용한다는 점이 특징이다.

간단한 예제를 만들어보자

const optionDongsu [1991, 'BackEnd']
const optionMinsu [1989, 'FrontEnd']

update.apply(dongsu, optionDongsu)
update.pally(minsu, optionMinsu)

# 이런식으로 사용할 수 있다
# ThisArg가 필요없는 경우 null을 써도된다.
# non-strict-mode에서 실행중이라면 null과 undefined는 전역객체로 대체되고, 기본값은 레퍼객체로 대체됩니다.

const num [1,4,3,5,2]

Math.max.apply(null, num) // 5
Math.min.apply(null, num) // 1


3. bind()

마지막으로 bind() 입니다. bind를 사용하게 되면 this의 값이 영구적으로 바뀌기 때문에 상황에 잘 맞춰 사용하는 것이 중요합니다.

한번 bind를 사용한 함수는 그 뒤의 call, apply, 그 외의 bind 함수와 함께 사용할 수 없습니다.

bind에 매개변수를 넘기면 항상 그 매개변수를 가지는 새로운 함수를 만듭니다.

예제를 통해 확인해 봅시다!

constNewDongsu update.bind(dongsu)
// NewDongsu의 thisArg는 dongsu 객체의 this를 가지는 update함수와 같은 기능을 하는 새로운 객체가 됩니다.

NewDongsu('1991', 'test')
// dongsu = { name: dongsu, birthYear: '1991', occupation: 'test'}
NewDongsu.call(minsu, 1989, 'test2')
// dongsu = { name: dongsu, birthYear: '1989', occupation: 'test2'}

이렇게 바인드를 통해 thisArg를 dongsu로 영구적으로 변경할 수 없도록 만들어줬기 때문에 위와 같은 결과가 발생합니다.



반응형

'javascript' 카테고리의 다른 글

Primitive Type & Reference Type  (0) 2019.05.29
Call stack & Event loop  (0) 2019.05.28
ES6 화살표함수(arrow function) & thisArg  (0) 2018.09.13
Comments