this 키워드

zwundzwzig·2022년 11월 4일
0

[javascript]

목록 보기
10/13
post-thumbnail

(Node.JS 서버 환경에서의) this 키워드에 대해 알아보자

전역 객체를 바인딩하는 경우

// nodeJS 서버 환경에선 global 객체를 바인딩
console.log(this === global); // true

// 웹 브라우저에서는 window 객체를 바인딩
console.log(this === window); // true

이렇듯 전역 컨텍스트에서의 this는 전역 객체 global을 참조한다.

function someFunc() {
	return this
}

someFunc() === global || window; // true

함수 안에서의 비엄격 모드 Sloppy mode에서도 this는 전역 객체 global을 참조한다.

  • 하지만 this 리턴 전, 엄격 모드Strict mode를 사용하면 this는 전역 객체를 참조하지 않으며, 엄격 모드 내 정의되지 않은 this는 undefined가 된다.

따라서, this가 global을 참조할 경우, 생명 주기는 전역 객체처럼 서버의 실행부터 종료까지 유효하다.

메모리 리소스에 계속 존재하여 불필요한 메모리를 잡아먹는다!

지역 객체(함수)를 바인딩하는 경우

var player = {
  name: "amoeba",
  introduce: function () {
    return this.name;
  }
}
  
player.introduce(); // amoeba

메소드 안에서 this 키워드가 사용되면 this는 메소드 프로퍼티가 있는 객체를 참조한다.

function hello() {
  return this.name;
}

var player = {
  name: "amoeba",
  introduce: hello
}
  
player.introduce(); // amoeba

이렇게 this가 특정 함수 안에 위치하고 그 함수가 어떤 객체의 메소드로 활용되면, this는 player라는 지역 객체를 참조한다.

전역 객체가 아닌 이유는 동작되는 시점인 런타임(Runtime) 시점에 맞춰 this가 결정되기 때문이다!

즉, 함수를 호출할 때 함수가 어떻게 호출됐는지에 따라 this에 바인딩할 객체가 동적으로 결정된다.

call(), apply(), bind() 메소드

this가 참조할 대상 객체를 다른 문맥으로 넘기려면 call이나 apply 메소드를 활용할 수 있다.

call()

Return Value: call 메소드는 this 값과 각각 전달된 인수와 함께 함수를 호출한다.

이미 할당되어있는 다른 객체의 함수/메소드를 호출하는 해당 객체에 재할당할 때 사용됩니다. this는 현재 객체(호출하는 객체)를 참조합니다. 메소드를 한번 작성하면 새 객체를 위한 메소드를 재작성할 필요 없이 call()을 이용해 다른 객체에 상속할 수 있습니다.
by MDN

➡️ 즉, 함수에 call 메소드와 그 안에 인자를 활용해 this를 재할당할 수 있다.

function howToStart(name, location) {
  this.name = name;
  this.location = location;
}

function bootcamp(name, location) {
  howToStart.call(this, name, location);
  this.merit = "community";
}

var nomad = new howToStart("nico", "Online");
var wecode = new bootcamp("Wecode37th", "Seolleung");

생성자 함수로 객체를 생성할 때 체이닝에도 사용 가능하다.

위 예시에서 call 메소드를 활용해 첫 번째 인자에 this를 넣어 howToStart 함수에 바인딩 시킨 후 이후 인자에 기존 함수의 인자를 받아 생성자 연결에 활용할 수 있다.

var language = "Korean";
var platform = "velog";

function coding() {
  var introduce = [
    this.language,
    'is my first language and',
    this.platform,
    'is my first platform.'
  ].join(' ');
  console.log(introduce)
  
var obj = {
  language: 'JavaScript',
  platform: 'Node.JS'
};
  
coding.call(obj); // JavaScript is my first language and Node.JS is my first platform.
coding.call(); // Korean is my first language and velog is my first platform.
coding(); // Korean is my first language and velog is my first platform.

대신 call 메소드에 인자를 전달하지 않으면 this는 전역 객체에 바인딩돼 전역 변수를 참조한다.

apply()

apply 메소드는 call 메소드와 거의 유사하지만, 두 번째 이후 인자로 배열 혹은 유사 배열 객체를 받는다.

그리고 첫 번째 인자로 비엄격 모드에서의 this, 즉 null이나 undefined를 받는다.

이미 존재하는 함수를 호출할 때 다른 this 객체를 할당할 수 있습니다. this 는 현재 객체, 호출하는 객체를 참조합니다. apply 를 사용해, 새로운 객체마다 메소드를 재작성할 필요없이 한 번만 작성해 다른 객체에 상속시킬 수 있습니다.
by MDN

var stringArray = ['a', 'b,'];
var numberArray = [0, 1, 2];
stringArray.push.apply(stringArray, numberArray);

console.log(stringArray) // ['a', 'b', 0, 1, 2];

이런 식으로 별다른 for문과 같은 함수들 없이 배열의 각 인덱스를 하나로 합칠 수 있다.

concat 메소드와 달리 새로운 배열을 만들지 않는다.

bind()

인자로 받는 함수에 this를 바인딩시키는 메소드이다.

this.way = "Offline";

var nomad = {
  way = "Online",
  howToStudy = function() { return this.way; }
};

nomad.howToStudy(); // "Online"

var wecode = module.howToStudy;
wecode(); // "Offline" - 함수가 전역 스코프에서 호출돼 전역 객체를 참조하기 때문!

var afterWecode = wecode.bind(nomad);
// bind 메소드를 활용해 인자로 받은 객체로 this를 바인딩 시킬 수 있음!
afterWecode(); // "Online"
profile
개발이란?

0개의 댓글