TIL 53 day 3장 This

Winney·2020년 12월 31일
0

코어자바스크립트

목록 보기
3/6
post-thumbnail

This

  • this는 실행 컨텍스트가 생성될 때 함께 결정 => 함수를 호출 할 때!!

전역공간에서의 this

  • 전역공간에서의 this : 전역객체
  • 브라우저 : window, Node.js : global
  • 전역 변수를 설정하면 JS 엔진은 이를 전역객체의 프로퍼티로도 할당
var a = 1;
console.log(a); // 1
console.log(window.a); // 1
console.log(this.a); // 1

위와 같은 결과가 나타나는 이유
: JavaScript의 모든 변수는 특정 객체의 프로퍼티로 동작하기 때문
특정객체 = 실행 컨텍스트의 LexicalEnvironment
=> 전역번수 선언 시 JavaScript 엔징은 이를 전역객체의 프로퍼티로 할당
but. 처음부터 전역객체의 프로퍼티로 할당한 경우에는 삭제가 되는 반면 전역변수로 선언한 경우 삭제가 되지 않는다.

메서드 vs 함수 내의 this

  • 함수와 메서드는 미리 정의한 동작을 수행하는 코드 뭉치
  • 차이 : 독립성
var func = function (x) {
	console.log(this, x);
}
func(1); // Window{...} 1

var obj = {
	method: fuc
};
obj.method(2); // {method: f } 2
  • 함수로서 호출
  • 메서드로 호출 : 함수 앞에 (.)이나 []가 있을 경우

메서드 내부의 this

  • this에는 호출한 주체에 대한 정보가 담긴다.
var obj1 = {
  outer: function() {
    console.log(this); // obj1
    var innerFunc = function() {
      console.log(this); // Window
    }
    innerFunc();
    var obj2 {
      innerMethod: innerFunc
    };
    obj2.innerMethod(); // obj2
  }
}
obj1.outer();

위의 차이는 (.)이 있느냐 없느냐의 차이
메서드로서의 함수는 .가 있고 해당 객체를 바라본다.

메서드 내부 함수의 this 우회 방법

var obj1 = {
  outer: function() {
    console.log(this);
    var innerFunc1 = function() {
      console.log(this);
    };
    innerFunc1();
    var self = this;
    var innerFunc2 = function() {
      console.log(self);
    };
    innerFunc2();
  }
};
obj1.outer();
  • this가 전역객체를 바라보지 않고 해당 객체에 보이게 하는 방식

this 바인딩을 하지 않는 함수

  • 화살표 함수(ES6 추가)
  • 화살표 함수는 실행 컨텍스트를 생성 할 때 this 바인딩 과정 자체가 빠지게되어 상위 스코프의 this를 그대로 활용 가능하다.

콜배 함수 호출 시 해당 함수 내부에서의 this

  • 콜백함수도 함수
  • this는 전역객체를 참조
  • 제어권을 받은 함수에서 콜백 함수에 별도로 this가 될 대상을 지정시 그 대상을 참조
setTimeout(function() {console.log(this);}, 300); // 1) window

[1,2,3,4,5].forEach(function(x) {
  console.log(this, x); // 2) window
});

document.body.innerHTML += `<button id = 'a'>클릭</button>`;
document.body.querySelector('#a').addEventListener('click', function(a) {
  console.log(this,a); // 3) 엘리먼트와 클릭 이벤트 정보
})

3)의 경우 html 엘리먼트에 'click'이벤트 => 콜백함수의 첫번째 인자로 삼아 함수 실행 => 엘리먼트 정보와 이벤트 정보가 담긴 객체 출력
addEventListener 메소드 앞에 .이 있기 때문에 앞의 this즉, querySelector를 상속하도록 되어 있다.

생성자 함수 내부에서의 this

객체지향언어에서

  • 생성자 : class
  • 클래스를 통해 만든 객체 : instance
  • JS는 함수에 생성자로서의 역할을 함께 부여
  • new 명령어와 함께 함수를 호출하면 해당 함수가 생성자로서 동작
    어떤 함수가 생성자로서 호출 => 내부의 this는 새로 만들 구체적인 인스턴스 자신
var Cat = function(name, age) {
	this.bark = '야옹';
    this.name = name;
    this.age = age;
};
var choco = new Cat('초코', 6);
var nabi = new Cat('나비', 8);
console.log(choco, nabi);

결과

Cat {bark: "야옹", name: "초코", age: 6}; 
Cat {bark: "야옹", name: "나비", age: 8};
  • 생성자 함수 호출(/w new)
    => 생성자의 prototype 프로퍼티를 참조하는 proto라는 프로퍼티가 있는 객체(인스턴스) 생성
    => 미리 준비된 공통 속성 및 개성을 해당 객체(this)에 부여
    => 구체적 인스턴스 생성

명시적인 this 바인딩 방법

1) call 메서드

  • 메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령
  • 첫번째 인자 : this 바인딩, 이후 인자 : 함수의 매개변수
  • 그냥 함수 호출 : this가 전역객체 참조
  • call 메서드 : 임의의 객체를 this로 지정
  • 메서드도 call 메서드를 이용해 임의의 객체를 this로 지정가능
var func - function(a, b, c) {
	console.log(this, a, b, c);
};
func(1, 2, 3); // Window{...} 1, 2, 3
func.call({x : 1}, 4, 5, 6); // { x : 1 } 4 5 6 

2) apply 메서드

  • apply 메서드는 call 메서드와 기능적으로 동일
  • 두번째 인자를 배열로 받아 해당 배열의 요소들을 호출할 함수의 매개변수로 지정

유사배열객체(array-like object)에 배열 메서드 사용

  • 키가 0 또는 양의 정수인 프로퍼티가 존재하고 length 프로퍼티의 값이 0 또는 양의 정수인 객체 => call 또는 apply 메서드를 이용해 배열 메서드 차용 가능
  • 배열처럼 인덱스와 length 프로퍼티를 지니는 문자열도 가능
    but. 문자열은 length 프로퍼티가 읽기 전용이므로 원본 문자열에 변경을 가하는 메서드는 에러(push, pop, shift, unshift 등)
  • 유사배열객체 및 순회 가능한 모든 종류의 데이터 타입을 배열로 전환하는 메서드 : Array.from

3) bind 메서드

  • call과 비슷하나 즉시 호출하지 않고 넘겨 받은 this 및 인수들을 바탕으로 새로운 함수 반환
  • 함수에 this를 미리 적용 및 부분 적용 함수를 구현하는 두 가지 목적
profile
프론트엔드 엔지니어

0개의 댓글