this

gusdnr814Β·2021λ…„ 5μ›” 6일
0

Javascript

λͺ©λ‘ 보기
46/55

πŸ“š Reference


javascript.info, https://ko.javascript.info/object-methods
PoiemaWeb, https://poiemaweb.com/es6-arrow-function

μ°Έκ³  μ‚¬μ΄νŠΈμ— λ‚΄μš©μ„ 개인적으둜 λ³΅μŠ΅ν•˜κΈ° νŽΈν•˜λ„λ‘ μž¬κ΅¬μ„±ν•œ κΈ€μž…λ‹ˆλ‹€.
μžμ„Έν•œ μ„€λͺ…은 μ°Έκ³  μ‚¬μ΄νŠΈλ₯Ό μ‚΄νŽ΄λ³΄μ‹œκΈ° λ°”λžλ‹ˆλ‹€.


μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 자유둜운 this


μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ thisλŠ” λ‹€λ₯Έ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ this와 λ™μž‘ 방식이 λ‹€λ¦…λ‹ˆλ‹€. λͺ¨λ“  ν•¨μˆ˜μ—μ„œ thisλ₯Ό μ„ μ–Έν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ‹€λ§Œ, ν•¨μˆ˜κ°€ 호좜되기 μ „κΉŒμ§€ thisμ—λŠ” 값이 ν• λ‹Ήλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. this의 값은 λŸ°νƒ€μž„ 쀑에 κ²°μ •λ˜κ³ , ν•¨μˆ˜κ°€ μ–΄λ””μ„œ μ •μ˜λ˜μ—ˆλŠ”μ§€μ— 상관없이 thisλŠ” . μ•žμ˜ 객체가 무엇인가에 따라 자유둭게 κ²°μ •λ©λ‹ˆλ‹€.

const person1 = {
  name: 'Tomas',
  age: 27
};
const person2 = {
  name: 'James',
  age: 30
};

function sayHi() {
  console.log(this.name, this.age);
}

// λ³„κ°œμ˜ κ°μ²΄μ—μ„œ λ™μΌν•œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
person1.f = sayHi;
person2.f = sayHi;

// 'this'λŠ” '점(.) μ•žμ˜' 객체λ₯Ό μ°Έμ‘°ν•˜κΈ° λ•Œλ¬Έμ— this 값이 λ‹¬λΌμ§‘λ‹ˆλ‹€.
person1.f(); // Tomas
person2.f(); // James

객체 없이 this ν˜ΈμΆœν•˜κΈ°

function sayHi() {
  'use strict'
  console.log(this);
}

function sayBye() {
  console.log(this);
}

sayHi(); // undefined
sayBye(); // window

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 엄격 λͺ¨λ“œ κΈ°μ€€μœΌλ‘œ μœ„ μ½”λ“œλŠ” μ°Έμ‘°ν•  객체가 μ—†κΈ° λ•Œλ¬Έμ— thisλŠ” undefinedλ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ 엄격 λͺ¨λ“œκ°€ μ•„λ‹ˆλΌλ©΄ μ „μ—­ 객체 windowλ₯Ό μ°Έμ‘°ν•˜μ—¬ thisλŠ” windowλ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

이런 μ‹μ˜ μ½”λ“œλŠ” λŒ€κ°œ μ‹€μˆ˜λ‘œ μž‘μ„±λœ κ²½μš°κ°€ λ§ŽμŠ΅λ‹ˆλ‹€. ν•¨μˆ˜ 본문에 thisκ°€ μ‚¬μš©λ˜μ—ˆλ‹€λ©΄, 객체 λ‚΄μ—μ„œ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  것이라고 μ˜ˆμƒν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€.

자유둜운 this의 문제점

λ‹€λ₯Έ μ–Έμ–΄λ₯Ό μ‚¬μš©ν•˜λ‹€ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ λ„˜μ–΄μ˜¨ κ°œλ°œμžλŠ” thisλ₯Ό ν˜Όλ™ν•˜κΈ° μ‰½μŠ΅λ‹ˆλ‹€. thisλŠ” 항상 λ©”μ„œλ“œκ°€ μ •μ˜λœ 객체λ₯Ό μ°Έμ‘°ν•  것이라고 μ°©κ°ν•©λ‹ˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ thisλŠ” λŸ°νƒ€μž„μ— κ²°μ •λ©λ‹ˆλ‹€. λ©”μ„œλ“œκ°€ μ–΄λ””μ„œ μ •μ˜λ˜μ—ˆλŠ”μ§€μ— 상관없이 thisλŠ” . μ•žμ˜ 객체가 무엇인가에 따라 자유둭게 κ²°μ •λ©λ‹ˆλ‹€.

μ΄λ ‡κ²Œ thisκ°€ λŸ°νƒ€μž„μ— κ²°μ •λ˜λ©΄ 쒋은 점도 있고 λ‚˜μœ 점도 μžˆμŠ΅λ‹ˆλ‹€. ν•¨μˆ˜(λ©”μ„œλ“œ)λ₯Ό ν•˜λ‚˜λ§Œ λ§Œλ“€μ–΄ μ—¬λŸ¬ κ°μ²΄μ—μ„œ μž¬μ‚¬μš©ν•  수 μžˆλ‹€λŠ” 것은 μž₯μ μ΄μ§€λ§Œ, 이런 μœ μ—°ν•¨μ΄ μ‹€μˆ˜λ‘œ μ΄μ–΄μ§ˆ 수 μžˆλ‹€λŠ” 것은 λ‹¨μ μž…λ‹ˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ thisλ₯Ό λ‹€λ£¨λŠ” 방식이 쒋은지, λ‚˜μœμ§€λŠ” μš°λ¦¬κ°€ νŒλ‹¨ν•  λ¬Έμ œκ°€ μ•„λ‹™λ‹ˆλ‹€. κ°œλ°œμžλŠ” this의 λ™μž‘ 방식을 μΆ©λΆ„νžˆ μ΄ν•΄ν•˜κ³  μž₯점을 μ·¨ν•˜λ©΄μ„œ μ‹€μˆ˜λ₯Ό ν”Όν•˜λŠ” 데만 μ§‘μ€‘ν•˜λ©΄ λ©λ‹ˆλ‹€.


thisκ°€ μ—†λŠ” ν™”μ‚΄ν‘œ ν•¨μˆ˜


ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” 일반 ν•¨μˆ˜μ™€λŠ” 달리 thisλ₯Ό 가지지 μ•ŠμŠ΅λ‹ˆλ‹€. ν™”μ‚΄ν‘œ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ this에 μ ‘κ·Όν•œλ‹€λ©΄, μ™ΈλΆ€ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ—μ„œ this 값을 κ°€μ Έμ˜΅λ‹ˆλ‹€. μ•„λž˜λŠ” sayHi() ν•¨μˆ˜μ˜ μ‹€ν–‰ μ½˜ν…μŠ€νŠΈ μ•ˆμ˜ thisλ₯Ό μ°Έμ‘°ν•˜κ²Œ λ©λ‹ˆλ‹€.

const user = {
  name: "Tomas",
  sayHi() {
    const arrow = () => console.log(this.name);
    arrow();
  }
};

user.sayHi(); // Tomas

λ³„κ°œμ˜ thisκ°€ λ§Œλ“€μ–΄μ§€λŠ” 것을 μ›ν•˜μ§€ μ•Šκ³ , μ™ΈλΆ€ ν•¨μˆ˜μ— μžˆλŠ” thisλ₯Ό μ΄μš©ν•˜κ³  싢은 경우 ν™”μ‚΄ν‘œ ν•¨μˆ˜κ°€ μœ μš©ν•©λ‹ˆλ‹€.

이런 νŠΉμ§•μ€ μ•„λž˜ μ˜ˆμ‹œμ²˜λŸΌ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const group = {
  title: 'crew',
  students: ['Tomas', 'James', 'Sam'],
  showList() {
    this.students.forEach(
      student => console.log(`${this.title}: ${student}`)
    );
  }
};

group.showList();

forEach() λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λ‘œ ν™”μ‚΄ν‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν–ˆκΈ° λ•Œλ¬Έμ—, ν™”μ‚΄ν‘œ ν•¨μˆ˜ 내뢀에 thisλŠ” μ™ΈλΆ€ ν•¨μˆ˜ showList() ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μ•ˆμ˜ this κ°’κ³Ό λ™μΌν•΄μ§‘λ‹ˆλ‹€.

λ§Œμ•½μ—, μœ„ μ½”λ“œμ—μ„œ ν™”μ‚΄ν‘œ ν•¨μˆ˜ λŒ€μ‹ μ— 일반 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν–ˆλ‹€λ©΄ μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€.

const group = {
  title: 'crew',
  students: ['Tomas', 'James', 'Sam'],
  showList() {
    'use strict'
    this.students.forEach(function(student) {
      // TypeError: Cannot read property 'title' of undefined
       console.log(`${this.title}: ${student}`);
    });
  }
};

group.showList();

이 λΆ€λΆ„μ—μ„œ μ•Œμ•„μ•Όν•  점은 λ‚΄λΆ€ν•¨μˆ˜λŠ” 일반 ν•¨μˆ˜, λ©”μ†Œλ“œ, μ½œλ°±ν•¨μˆ˜ μ–΄λ””μ—μ„œ μ„ μ–Έλ˜μ—ˆλ“  관계없이 thisλŠ” μ „μ—­ 객체λ₯Ό λ°”μΈλ”©ν•˜κ³  엄격 λͺ¨λ“œμ—μ„œλŠ” undefinedκ°€ λ©λ‹ˆλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈ μ „λ¬Έκ°€ λ”κΈ€λΌμŠ€ ν¬λ½ν¬λ“œλŠ” β€œμ΄κ²ƒμ€ 섀계 λ‹¨κ³„μ˜ κ²°ν•¨μœΌλ‘œ λ©”μ†Œλ“œκ°€ λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ μžμ‹ μ˜ μž‘μ—…μ„ λ•κ²Œ ν•  수 μ—†λ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.”라고 λ§ν•©λ‹ˆλ‹€.

μœ„ μ½”λ“œμ— 경우 forEach() λ©”μ„œλ“œμ˜ 콜백 ν•¨μˆ˜λ‘œ 일반 ν•¨μˆ˜κ°€ μ‚¬μš©λ˜μ–΄ 엄격 λͺ¨λ“œ κΈ°μ€€μœΌλ‘œ thisλŠ” undefinedλ₯Ό 가리킀고 undefined.title이 λ˜μ–΄ μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€.

new μ—°μ‚°μžμ™€ ν™”μ‚΄ν‘œ ν•¨μˆ˜

ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” thisκ°€ μ—†κΈ° λ•Œλ¬Έμ— ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” μƒμ„±μž ν•¨μˆ˜λ‘œ μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€. ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” new와 ν•¨κ²Œ ν˜ΈμΆœν•  수 μ—†μŠ΅λ‹ˆλ‹€.


addEventListener의 콜백 ν•¨μˆ˜μ˜ this


addEventListener()의 콜백 ν•¨μˆ˜μ˜ thisλŠ” addEventListenr() ν•¨μˆ˜μ— λ°”μΈλ”©λœ μš”μ†Œλ₯Ό κ°€λ¦¬ν‚΅λ‹ˆλ‹€. μ—¬κΈ°μ„œ 콜백 ν•¨μˆ˜λ₯Ό ν™”μ‚΄ν‘œ ν•¨μˆ˜λ‘œ μ •μ˜ν•  경우 thisλŠ” windowλ₯Ό 가리킀고 엄격 λͺ¨λ“œμ—μ„œλŠ” undefinedλ₯Ό κ°€λ¦¬ν‚΅λ‹ˆλ‹€.

const button = document.getElementById('myButton');
// 콜백 ν•¨μˆ˜λ‘œ 일반 ν•¨μˆ˜
button.addEventListener('click', function() {
  console.log(this === button); // true
  this.innerHTML = 'Clicked button';
});
const button = document.getElementById('myButton');
// 콜백 ν•¨μˆ˜λ‘œ ν™”μ‚΄ν‘œ ν•¨μˆ˜
button.addEventListener('click', () => {
  console.log(this === window); // true
  this.innerHTML = 'Clicked button';
});

apply, call, bind


apply(), call(), bind()λŠ” ν•¨μˆ˜ 객체의 ν”„λ‘œν† νƒ€μž… 객체가 κ°€μ§€λŠ” κΈ°λ³Έ λ©”μ„œλ“œμž…λ‹ˆλ‹€.

func.apply(thisArg, [argsArray]);
func.call(thisArg, arg1, arg2, ...);
func.bind(thisArg, arg1, arg2, ...);

thisArg μΈμžλŠ” ν•¨μˆ˜ λ‚΄λΆ€μ˜ this에 바인딩할 객체λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. argsArray, arg1, arg2 λ“±μ˜ μΈμžλŠ” ν•¨μˆ˜μ—μ„œ μ‚¬μš©ν•  인자λ₯Ό μ˜λ―Έν•˜λ©° 전달할 μΈμžκ°€ 없을 경우 μƒλž΅ κ°€λŠ₯ν•˜κ³ , λ©”μ„œλ“œ λ³„λ‘œ 인자λ₯Ό λ„˜κΈ°λŠ” 방식이 μ‘°κΈˆμ”© λ‹€λ¦…λ‹ˆλ‹€.

이 λ©”μ„œλ“œλ“€μ„ ν˜ΈμΆœν•˜λŠ” μ£Όμ²΄λŠ” ν•¨μˆ˜μ΄λ©° 본질적인 κΈ°λŠ₯은 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. λ‹€λ§Œ bind() λ©”μ„œλ“œμ˜ 경우 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³  λ°˜ν™˜λ§Œ ν•©λ‹ˆλ‹€.

const person = {
  name: "name",
  speak: function (age, gender) {
    console.log(this.name, age, gender);
  }
};

const person1 = {
  name: "Tomas"
};
const person2 = {
  name: "James"
};
const person3 = {
  name: "Sam"
};

person.speak.apply(person1, [30, "male"]);
person.speak.call(person2, 25, "female");
const info = person.speak.bind(person3, 15, 'male');
info();
// person.speak.bind(person3, 15, 'male')();

bind() ν•¨μˆ˜μ˜ 경우 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³  λ°˜ν™˜ν•˜κΈ° λ•Œλ¬Έμ— λ³€μˆ˜μ— λ‹΄μ•„ ν˜ΈμΆœν•˜κ²Œ λ©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 경우 μ½”λ“œκ°€ κΈΈμ–΄μ§€λ―€λ‘œ λ°˜ν™˜λœ ν•¨μˆ˜λ₯Ό λ³€μˆ˜μ— λ‹΄μ§€μ•Šκ³  λ°”λ‘œ μ‹€ν–‰ν•˜λŠ” 방법 λ˜ν•œ μžˆμŠ΅λ‹ˆλ‹€.

ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” thisκ°€ μ—†μ–΄μ„œ μ–΄λ–€ 것도 λ°”μΈλ”©μ‹œν‚€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ apply(), call(), bind() λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ thisλ₯Ό λ³€κ²½μ‹œν‚¬ 수 μ—†μŠ΅λ‹ˆλ‹€.

profile
Just Do It πŸ’ͺπŸ’’

0개의 λŒ“κΈ€