[JS] this는 왜 사용 하는 걸까? (ES5)

초이지수·2022년 10월 27일
0

JavaScript

목록 보기
4/4
post-thumbnail

결론부터 말하자면! 데이터 중심으로 접근하기 위해서!이다!

this에 대해 차근차근 알아보자!


🙋🏻‍♀️ this란

obj.name() 형태로 호출한 함수(메서드)에서 this로 인스턴스(오브젝트)를 참조한다

인스턴스(obj)는 실행 컨텍스트의 this 바인딩 컴포넌트에 바인딩됨
-> 그래서 함수 안의 this로 인스턴스(obj)를 참조할 수 있는 것!


🙋🏻‍♀️ this와 글로벌 오브젝트

글로벌 오브젝트에서 this는 글로벌 오브젝트를 참조한다.

글로벌 함수를 호출할 때 함수 앞에 글로벌 오브젝트를 작성할 수 없다.
-> 암묵적으로 글로벌 오브젝트로 간주되는 것이다.

☄️ this와 window 오브젝트의 관계

window는 JavaScript에서 만든 것이 아니고 글로벌 오브젝트의 스코프도 아니다.
Host 오브젝트 개념을 적용하기 때문에 window와 글로벌 오브젝트를 같은 선상에서 사용한다.

  • Host 오브젝트란
    window 오브젝트와 같이 다른 오브젝트를 마치 내 것 처럼 사용하는 개념

window = 글로벌 오브젝트로 생각해도 되지만 실체는 다름!!!!!!!!!!


🙋🏻‍♀️ this와 strict 모드

오브젝트.함수이름() 형태로 함수를 호출
글로벌 오브젝트는 오브젝트 이름이 없으니까 함수 이름만 작성해서 호출한다.

strict 모드에서는 window.music() 처럼 window를 글로벌 오브젝트로 작성해야한다.
함수 앞에 오브젝트를 작성하지 않으면
this 바인딩 컴포넌트에 undefined로 설정돼 this로 글로벌 오브젝트를 참조할 수 없다.

function music() {
  "use strict";
  return this;
};
var result = music(); // music 함수 앞에 오브젝트를 작성하지 않음
console.log(result);

// 실행 결과
// undefined

return this에서 this는 this 바인딩 컴포넌트를 참조하게 됨


🙋🏻‍♀️ this와 인스턴스

☄️ 인스턴스에서 this의 목적

this로 인스턴스를 참조해 this.name 형태로 프로퍼티에 접근

  • ex) function 오브젝트라면 name은 메서드
    number라면 프로퍼티 이름

☄️ proto 프로퍼티 접근

new 연산자로 인스턴스를 생성하면 prototype에 연결된 프로퍼티가 인스턴스 proto 에 첨부됨
= this.method() 형태로 proto 에 첨부된 method() 를 호출할 수 있다!

prototype에 연결된 메서드는 모든 인스턴스에서 공유하고 인스턴스마다 고유의 값을 유지한다.

var music = {};
music.Point = function(point) {
  this.point = point; // 2
};
music.Point.prototype.getPoint =
  function() {
  	console.log(this.point); // 4
  };
var obj = new music.Point(100); // 1
obj.getPoint(); // 3

// 실행 결과
// 100
  1. new 연산자를 사용해 music.Point 생성자 함수를 호출해 인스턴스를 만듦
  2. this가 생성한 인스턴스를 참조하므로, 인스턴스의 point 프로퍼티에 넘겨준 값 100을 할당
  3. obj 인스턴스의 getPoint() 메서드 호출
  4. obj.getPoint() 로 호출
    this가 obj 참조
    obj는 music.Point 인스턴스
    music.Point 인스턴스의 point 값 출력

인스턴스마다 값을 가져갈 수 있고 proto 에서 전체 인스턴스에서 공유할 수 있는 메서드를 갖고 있음
-> class 관점의 접근 = 클래스는 하나의 덩어리. 데이터 중심 -> 가독성이 좋고 유지보수가 쉬움


🙋🏻‍♀️ this와 call() apply()

  • apply() 메서드는 두 번째 파라미터 수가 유동적일 때 사용
  • call() 메서드는 파라미터 수가 고정일 때 사용

☄️ this와 call()

  • getTotal.call(this, 10, 20)
    함수.call 형태로 작성
    10과 20을 파라미터 값으로 넘겨줌

  • 첫 번째는 파라미터에 호출된 함수에서 this로 참조할 오브젝트 작성
    일반적으로 this를 사용하지만, this 이외에 다른 오브젝트 사용 가능
    -> this 바인딩 컴포넌트에 첫 번째 파라미터에 작성한 오브젝트가 바인딩 됨

  • 두 번째부터 파라미터 값으로 넘어감

"use strict";
var value = 100;
function get(param) {
  return param + this.value; // 2
};
var result = get.call(this, 20); // 1
console.log(result);

// 실행 결과
// 120
  1. 첫 번째 파라미터에 this 작성
  2. 20으로 넘긴 파라미터가 param에 할당되고
    this가 글로벌 오브젝트를 참조하므로, 글로벌 변수인 var value=100 값을 사용할 수 있음

this로 참조할 오브젝트를 변경할 수 있는 것이 call() 메서드의 특징


☄️ this와 apply()

  • getTotal.apply(this, [10, 20])
    함수 호출 방법은 call()과 같음
    파라미터가 배열인 것이 다른점

this와 arguments

var obj = {0: 10, 1: 20, 2: 30};
var data = [4, 5, 6]

function get() { // 2
  for (k = 0; k < arguments.length; k++) {
    console.log(arguments[k] + this[k]);
  };
};
get.apply(obj, data); // 1

// 실행 결과
// 14
// 25
// 36
  1. obj는 호출된 함수에서 this로 참조하는 오브젝트. data는 get 함수로 넘겨줄 파라미터 값.
    (파라미터 값이 apply() 메서드를 사용해서 유동적이지만 위의 예시에서는 배열이므로 하나인 것)

  2. 두 번째 파라미터 [4, 5, 6] 을 arguments를 사용해서 계산
    (파라미터 수가 유동적이므로 arguments를 사용하는게 편리함)
    get 함수에 파라미터 이름을 작성하지 않았음
    arguments 프로퍼티로 파라미터 값을 사용할 수 있음
    arguments의 length 만큼 반복하게 될ㄷ 때 k가 0이면 arguments 값은 4
    this는 obj를 참조하게 되니까 k가 0이면 this 값은 10

  3. get() 함수 코드는 바뀌지 않음
    넘겨주는 파라미터 값과 this로 참조할 오브젝트만 변경하면 됨


☄️ call() apply() 메서드를 사용하는 이유

데이터 중심으로 접근 하기 위해

get.apply(obj, data); 여기 코드의 데이터만 바꿔준다면 함수 안에 있는 코드 변경 없이 데이터 처리를 할 수 있다!


🙋🏻‍♀️ this와 콜백 함수

var obj = { value: 100 };
var data = [5, 6, 7];

function callback(element, index, data) { // 콜백 함수
	return element + this.value; // 3 5
};
function get(data) { // get 함수 아래에서 호출함
	return data.map(callback, obj); // 2 4
};
var result = get(data); // 1
console.log(result);

// 실행 결과
// [105, 106, 107]
  1. get 함수를 호출하면서 data(파라미터 값)를 넘겨줌
  2. ES5의 map(), forEach() 처럼 콜백 함수가 있는 메서드는
    첫 번째 파라미터에 callback 함수 작성 : 배열의 element를 하나씩 읽어가며 반복하게 됨
    두 번째 파라미터에 this로 참조할 오브젝트 작성 : callback 함수에서 this로 참조할 오브젝트
    -> callback 함수가 호출되면 element는 5, index는 0, data는 [5, 6, 7] 설정
  3. return element + this.value;
    5 + 100
    105 반환
  4. map 메소드에서 최종적으로 반환해 배열에 105 첨부
    callback 함수 호출
  5. element를 6으로 호출하면서 반복

💡 그래서 this는 왜 쓰는 거죠?

위의 예시에서 callback 함수는 독립적이다.
map 메서드는 callback 함수가 어떤 일을 하는지 알 필요가 없다.
map 메서드의 본분은 callback 함수를 호출하면서, 두 번째 파라미터에 오브젝트가 있으면 넘겨주는 것이기 때문 (map 메서드는 데이터를 넘겨주는 게 목적임)

  1. callback 함수에서 처리해야하는 elementm, index, data는 파라미터 (배열)로 넘겨줌
  2. this로 참조할 오브젝트는 map 메서드에서 넘겨줌
  3. callback 이 처리함

각자 독립성을 갖고 각자 처리해야할 일을 하면 데이터만 바꿔주면 계속 처리 가능하다!!!!!!!

= 데이터 중심으로 처리 하겠다!!!!!!!!!!


  1. call() apply() 메서드
  2. callback 함수가 있는 메서드
  3. class, instance

이 개념들을 각각 하나의 묶음으로 생각해 코드를 짠다면 this를 활용해 조금 더 효율적인 코드를 짤 수 있을 것이다!

profile
닫혀 있어서 벽인 줄 알고 있지만, 사실은 문이다.

0개의 댓글