[JavaScript]this의 용법

박광민·2023년 3월 21일
0

this란 무엇인가?

  • 자바스크립트 내에서 this는 함수가 실행되는 공간을 의미
    -> '누가 나를 불렀는가?'를 뜻함
    -> 즉, 선언이 아닌 호출방식에 따라 this에 바인딩 되는 객체가 결정됨
    (this가 실행되는 곳을 보면됨)

  • 보통 this는 4가지규칙으로 쓰임
    1.함수호출
    2.메써드호출
    3.생성자함수호출
    4.apply/call/bind 호출

상황별 this가 어디에 binding?

!! binding(바인딩)이란? -> 변수를 값 또는 함수와 연결하는 것을 의미

1. 함수 호출

  • strict mode가 아닌 이상 무조건 글로벌 객체(window)를 가리킴
const age = 1; 
// global object

function go() {
  console.log(this.age);
  // this === global object : 브라우저에서는 window를 가리킴
}

go(); // 1 (글로벌 객체 실행)

// -------------------------------------------------------

const age = 100;

function go() {
  const age = 99;
  gogo(age);
}
function gogo(age) {
  console.log(this.age); 
  // 100
}

go(); 
// 100

// this.age가 전역객체의 age를 참조
// gogo()함수는 전역스코프에서 호출되지 않음 
// -> 즉, this는 전역객체를 가르킴
// go()함수 내부에서 age 99를 재할당해도 gogo()함수에서 전달된 age 매개변수를 받아들이지만 
// 여전히 this age는 전역객체의 age값을 출력'

1-1. strict mode(엄격한 모드)

  • 엄격한 모드에서 일반함수 실행방식을 쓰면 window객체를 가리키지않음
    -> this는 undefined가 되어 에러 발생
    -> 개발할 때 window객체를 본인도 모르게 건드려 에러 발생을 막기위함
"use strict";

const name = "pkm";

function go() {
  console.log(this.name); 
  // 'this' === undefined 
  // error
}

go();

2.메써드 호출

  • 메써드 호출 시 메써드 내부코드에서 사용된 this
    -> 해당 메써드를 호출한 객체로 바인딩
const person = {
  
  firstName: 'Kwangmin',
  lastName: 'Park',
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  },
};
 
person.fullName(); //"Kwangmin Park"

// -------------------------------------------------------

const num = 0;
 
function goNum() {
  console.log(this.num);
}
 
goNum(); 
//0
 
const obj = {
  num: 200,
  func: goNum,
};
 
obj.func(); 
//200

3. 생성자 함수 호출

  • new함수를 실행하면 해당 함수의 값은 빈 객체가 됨
    -> new와 같이 쓰는 this는 return이 없어도 자동으로 return으로 할당됨
  • 화살표 함수는 생성자 함수로 사용할 수 없음
function Person() {
  console.log(this.age); 
  // undefined
  
  this.age = 100;
  // this 값은 new를 만나 자동으로 return 되어 아래 콘솔에 100할당됨
  
  console.log(this.age); 
  // 100
}

new Person();

// -------------------------------------------------------

function p(c, i) {
  this.c = c;
  this.i = i;
}
new p([1, 2, 3], 100); 
// this가 new를 만나 자동 return
// p {c:[123],i:100}

// -------------------------------------------------------

function go() {
  this.age = 100;
  this.aa = 1;
  return 3; // return이 안먹음
}
new go(); // {age: 100, aa: 1}
// new에서는 return이 없어도 this가 있으면 결과값이 들어감

// -----> 강제로 상수를 return시켜도 작동하지 않음

// -------------------------------------------------------

function go() {
  const age = 100;
  return { gogogo: 100 };
}
new go();
// {gogogo : 100};

// -----> but!! 객체를 return하면 함수는 객체 return 값을 채택함
 

4. call / apply / bind 호출

  • this는 위 세함수의 파라미터로 들어온 객체로 바인딩

4-1 call()함수

const age = 100;
function go() {
 console.log(this.age);
}

const pkm = {
 age: 99,
 log: go
};

go(); // 100
go.call(); // 100
go.call(pkm); // 99

// go를 실행하고, this값을 pkm으로 지정함 -> this는 pkm임
// call : go함수를 실행하고 call에 인자를 줌으로 this를 지정

// call()함수의 인자값으로 변수를 넣어줌으로 this를 변수로 할당
// -> 아무인자도 넣지 않으면 일반 함수 실행과 동일하여 글로벌 스코프로 this가 바인딩됨

// -------------------------------------------------------

// call은 인자를 무제한 받음
// this는 pkm을 받고 뒤 1,2,3은 go의 인자 값으로 들어감

function go(a, b, c) {
 console.log(this.age);
 console.log(a, b, c);
}
const pkm = { age: 123 };
go.call(pkm, 1, 2, 3);

/*
123
1 2 3
*/

4-2 apply()함수

  • call()함수와 apply()함수의 실행하는 방법은 동일
  • 차이점
    • call()함수 -> 두번째부터 인자목록을 받음
    • apply()함수 -> 인자배열 하나를 받음
const age = 100;
function go() {
  console.log(this.age);
}

const pkm = {
  age: 99,
  log: go
};

go(); // 100
go.call(); // 100
go.apply(pkm); // 99 => this : pkm

// -------------------------------------------------------

function go(a, b, c) {
  console.log(this.age);
  console.log(a, b, c);
}

const pkm = { age: 123 };
// go.call(pkm,1,2,3,4,5,6);
go.apply(pkm, [1, 2, 3, 4, 5, 6]);

/*
123
1 2 3
*/

// 2번째 인자의 요소를 배열로 무제한 줄수있고 순서대로 a,b,c로 들어감
// 배열에 맞는 조건이면 apply  (apply은 인자가 2개 this가리키는 것, 배열)

4-3 bind()함수

  • bind()함수는 this 키워드를 주어진 변수로 설정하고, 앞쪽의 매개변수도 자신의 인자를 사용해 미리 순서대로 채워놓은 새로운 함수를 반환함
const age = 100;
function go() {
  console.log(this.age);
}
const pkm = {
  age: 99,
  log: go
};
// 새로운 함수를 반환
const gogo = go.bind(pkm);
const gogogo = go;
gogo(); // 99
gogogo(); // 100
go.call(pkm); // 99
profile
developer(Frontend)

0개의 댓글