this [JavaScript]

SnowCat·2022년 12월 26일
0
post-thumbnail

this

  • 이름 그대로 자기자신을 가리킬거 같지만..
const dog = {
  name: 'Nurung',
  sayName: function() {
    console.log(this.name); //누렁이
  	function sayId() {
      console.log(this); // window
    }
    sayId();
  }
}

dog.sayName(); //누렁이 window
  • 예문처럼 메소드에서의 이름 출력을 시도하면 누렁이가 아닌 전역 객체가 출력되는 등 다른 언어에서의 this와는 다르게 동작함
  • 호출 방식에 따라 this가 달라짐에 주의해야함. 즉 누가 this를 불렀는가를 의식할 필요가 있음

1. Global Context

'use strict';
console.log(this === window); // true
  • 전역 문맥상에서 this 호출 -> strict 여부에 관계없이 this = 전역 객체

2. Functional Context

2-1. 함수를 메소드 상에서 호출한 경우

const dog = {
  name: 'Nurung',
  sayName: function() {
    console.log(this.name);
}
dog.sayName(); //누렁이
  • 메서드를 호출한 객체가 this로 설정됨, 따라서 예문에서 this = dog

2-2. 함수를 단독 호출한 경우

'use strict'
function getThis() {
  return this;
}

console.log(getThis()); //undefined
  • 어떤 객체가 this를 호출했는지 알수 없음, 이 경우에는 this는 undefined로 설정됨
function getThis() {
  return this;
}

console.log(getThis()); //window
  • 엄격모드가 아닌 경우는 this가 명시적으로 지정되지 않은 경우 전역 객체를 할당함, 즉 this = undefined -> 전역 개체(대체)

2-3. 콜백 함수의 경우

  • 콜백함수를 통해 실행되는 함수의 this를 따라감
function logThis() {
  "use strict";
  console.log(this);
}

[1, 2, 3].forEach(logThis); // undefined, undefined, undefined
setTimeout(logThis, 1000); // undefined
  • 두 케이스는 각각의 경우마다 logThis()를 수행하게 됨, 따라서 함수를 단독 호출한 경우임으로 this = undefined
[1, 2, 3].forEach(logThis, { name: "obj" });
// { name: 'obj' }, { name: 'obj' }, { name: 'obj' }
  • 이 경우는 forEach 함수에 명시적인 this를 지정함, this = { name: "obj" }

2-4. 화살표 함수의 경우

  • 화살표 함수에서 this는 자신을 감싼 lexial context
const globalObject = this;
const foo = () => this;
console.log(foo() === globalObject); // true
  •  예문에서는 global context에 코드가 작성되어 있음으로 foo()가 가리키는 this는 strict여부에 상관없이 전역 객체
const obj = { name: "obj" };

console.log(foo.call(obj) === globalObject); // true

const boundFoo = foo.bind(obj);
console.log(boundFoo() === globalObject); // true
  • 화살표 함수 내에서는 call(), bind(), apply()메서드를 사용하더라도 무시됨
var obj = {
  bar: function() {
    var x = (() => this);
    return x;
  }
};

var fn = obj.bar();
console.log(fn() === obj); // true

var fn2 = obj.bar;
console.log(fn2()() == window); // true
  • 화살표 함수의 this는 자신을 감싼 obj가 됨, 따라서 fn의 this = obj
  • fn2와 같이 호출없이 메서드를 참조하려 하는 경우 값이 달라질 수 있음에 주의, 이 경우 fn2의 this = 전역 객체

2-5 생성자

function Person(name) {
  this.name = name;
}
 
var nurung = new Person('nurung');
 
console.log(nurung.name); //누렁이
  • 생성자 함수가 생성한 객체가 this, 따라서 이 경우 this = Person

2-6 프로토타입 체인

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
  • 프로토타입 체인이 사용되는 경우라도 호출을 한 객체의 this를 가리킴, 따라서 p.f() 에서 가리키는 this = p

2-7 getter, setter

function sum() {
  return this.a + this.b + this.c;
}

var o = {
  a: 1,
  b: 2,
  c: 3,
  get average() {
    return (this.a + this.b + this.c) / 3;
  }
};

Object.defineProperty(o, 'sum', {
    get: sum, enumerable: true, configurable: true});

console.log(o.average, o.sum); // 2, 6

* 접근 또는, 설정하는 함수에서 this가 결정됨, 이 경우 o.sum이 가리키는 this는 o가 됨

3. DOM event

function bluify(e) {
  this.style.backgroundColor = "#A5D9F3";
}

const elements = document.getElementsByTagName("*");

for (const element of elements) {
  element.addEventListener("click", bluify, false);
}
  • 이벤트를 발생시킨 요소가 this가 됨, 이 경우는 클릭된 DOM요소가 this가 됨
<button onclick="alert(this.tagName.toLowerCase());"></button>
  • html 내부에 코드를 작성하는 경우 코드가 배치된 DOM요소가 this가 됨, 예문의 this = button
<button onclick="alert((function() { return this; })());"></button>
  • 함수 내부에 this가 나오는 경우 이전에 언급한 규칙을 따라감. 예문은 직접적인 this가 명시되어있지 않기 때문에 global object 반환

출처:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
https://nykim.work/71

profile
냐아아아아아아아아앙

0개의 댓글