[JavaScript] This

Peter·2022년 3월 3일
0

JavaScript

목록 보기
3/9
post-thumbnail

This

MDN this

// 웹 브라우저에서는 window 객체가 전역 객체
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"
  • 기본적으로 웹브라우저라면 window를 this가 가르킨다
  • this.b 로 값을 할당하더라도 this는 전역객체이므로 console.log(b)가 정상적으로 출력이 된다
function f1() {
  return this;
}

// 브라우저
f1() === window; // true

// Node.js
f1() === global; // true
  • 브라우저 상황과 노드 상황에서 this는 전역객체를 가르킨다
  • 하지만 strict mode에서 this는 실행 문맥을 가르키기 때문에 undefined 로 남아있다.

컨텍스트 부여하기

// call 또는 apply의 첫 번째 인자로 객체가 전달될 수 있으며 this가 그 객체에 묶임
var obj = {a: 'Custom'};

// 변수를 선언하고 변수에 프로퍼티로 전역 window를 할당
var a = 'Global';

function whatsThis() {
  return this.a;  // 함수 호출 방식에 따라 값이 달라짐
}

whatsThis();          // this는 'Global'. 함수 내에서 설정되지 않았으므로 global/window 객체로 초기값을 설정한다.
whatsThis.call(obj);  // this는 'Custom'. 함수 내에서 obj로 설정한다.
whatsThis.apply(obj); // this는 'Custom'. 함수 내에서 obj로 설정한다.
  • var a 가 전역 변수로 작용하기 때문에 whatThis 함수를 실행하게 되면 this는 'Global'이다
  • call, apply를 통해 컨텍스트를 부여할 수 있다.
  • 따라서 call, apply를 통해 obj를 설정해주면 this는 'Custom'을 의미한다
function add(c, d) {
  return this.a + this.b + c + d;
}

var o = {a: 1, b: 3};

// 첫 번째 인자는 'this'로 사용할 객체이고,
// 이어지는 인자들은 함수 호출에서 인수로 전달된다.
add.call(o, 5, 7); // 16

// 첫 번째 인자는 'this'로 사용할 객체이고,
// 두 번째 인자는 함수 호출에서 인수로 사용될 멤버들이 위치한 배열이다.
add.apply(o, [10, 20]); // 34
  • call 메소드를 통해 컨텍스트를 별도로 설정해줄 수 있다
  • apply는 어레이 형태로 인자를 넘긴다

bind 메소드

function f() {
  return this.a;
}

var g = f.bind({a: 'azerty'});
console.log(g()); // azerty

var h = g.bind({a: 'yoo'}); // bind는 한 번만 동작함!
console.log(h()); // azerty

var o = {a: 37, f: f, g: g, h: h};
console.log(o.a, o.f(), o.g(), o.h()); // 37, 37, azerty, azerty
  • bind를 통해 첫번째 인자로 컨텍스트를 묶어주고
  • f 함수의 리턴값으로 묶어준 컨텍스트를 보내줌
  • bind는 한 번만 동작
  • bind를 사용해서 할당한 함수는 새로운 함수로 생성

화살표 함수

var globalObject = this;
var foo = (() => this);
console.log(foo() === globalObject); // true


// 객체로서 메서드 호출
var obj = {func: foo};
console.log(obj.func() === globalObject); // true

// call을 사용한 this 설정 시도
console.log(foo.call(obj) === globalObject); // true

// bind를 사용한 this 설정 시도
foo = foo.bind(obj);
console.log(foo() === globalObject); // true
  • 화살표 함수는 생성될 때 this가 결정
  • 스스로의 this를 가지지 않고 함수가 정의된 스코프의 this를 가르킴
  • 상위의 this를 가르킴
  • 일반함수는 자체의 this를 가지고 있으며 화살표 함수는 this를 가지고 있지 않기 때문에 this를 사용하게 되면 같은 스코프의 this를 가르키게 됨

객체의 메소드

var o = {prop: 37};

function independent() {
  return this.prop;
}

o.f = independent;

console.log(o.f()); // logs 37
  • o 객체 안에 f함수가 할당하고 실행시키면 independent함수의 this.prop은 o.prop을 가르키게 됨
var o = {
  f:function() { return this.a + this.b; }
};
var p = Object.create(o);
p.a = 1;
p.b = 4;

console.log(p.f()); // 5
  • o의 객체의 f에 할당된 함수는 this.a, this.b를 다루고 있는데 아랫줄 Object.create를 통해 this는 p객체를 바라보게 된다
  • 아래에 a, b의 값을 할당함을 통해 f 함수는 연산이 가능해진다

생성자

function C() {
  this.a = 37;
}

var o = new C();
console.log(o.a); // 37


function C2() {
  this.a = 37;
  return {a: 38};
}

o = new C2();
console.log(o.a); // 38
  • 새로 생긴 객체의 this가 묶이게 된다
  • C2가 생성되면 return 으로 새로 생긴 객체에 묶인다

DOM 이벤트 처리

// 처리기로 호출하면 관련 객체를 파랗게 만듦
function bluify(e) {
  // 언제나 true
  console.log(this === e.currentTarget);
  // currentTarget과 target이 같은 객체면 true
  console.log(this === e.target);
  this.style.backgroundColor = '#A5D9F3';
}

// 문서 내 모든 요소의 목록
var elements = document.getElementsByTagName('*');

// 어떤 요소를 클릭하면 파랗게 변하도록
// bluify를 클릭 처리기로 등록
for (var i = 0; i < elements.length; i++) {
  elements[i].addEventListener('click', bluify, false);
}
  • 이벤트 리스너로 클릭상황에서 발생하는 함수의 this는 이벤트를 발생시킨 요소를 가르키게 된다.
  • 여기서 화살표함수를 사용하게 되면 이벤트를 발생시킨 요소가 아니라 window를 가르키게 된다.
profile
컴퓨터가 좋아

0개의 댓글