this

YeonnΒ·2024λ…„ 3μ›” 18일
0

JavaScript

λͺ©λ‘ 보기
18/23
post-thumbnail

πŸ“ 자기 μ°Έμ‘° λ³€μˆ˜( self-referencing variable )
μžμ‹ μ΄ μ†ν•œ 객체 λ˜λŠ” μžμ‹ μ΄ 생성할 μΈμŠ€ν„΄μŠ€λ₯Ό κ°€λ¦¬ν‚€λŠ” νŠΉμˆ˜ν•œ μ‹λ³„μž
μžμ‹ μ΄ μ†ν•œ 객체 λ˜λŠ” μžμ‹ μ΄ 생성할 μΈμŠ€ν„΄μŠ€μ˜ 'ν”„λ‘œνΌν‹°λ‚˜ λ©”μ„œλ“œ μ°Έμ‘° κ°€λŠ₯'

βœ”οΈ this ν‚€μ›Œλ“œ

ν•¨μˆ˜ 호좜 μ‹œ arguments 객체와 thisκ°€ μ•”λ¬΅μ μœΌλ‘œ ν•¨μˆ˜ 내뢀에 μ „λ‹¬λ˜κ³ , arguments 객체λ₯Ό 지역 λ³€μˆ˜μ²˜λŸΌ μ‚¬μš©ν•  수 μžˆλ“―μ΄, this도 지역 λ³€μˆ˜μ²˜λŸΌ μ‚¬μš©ν•  수 μžˆλ‹€. 이 λ•Œ, thisκ°€ κ°€λ¦¬ν‚€λŠ” κ°’, 즉 this 바인딩은 ν•¨μˆ˜ 호좜 방식에 μ˜ν•΄ λ™μ μœΌλ‘œ κ²°μ •λœλ‹€. μ—¬κΈ°μ„œ this 바인딩은 this와 thisκ°€ 가리킬 객체λ₯Ό 바인딩 ν•˜λŠ” 것을 μ˜λ―Έν•œλ‹€.

ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜λŠ” 방식에 따라 this에 바인딩 될 κ°’, 즉 this 바인딩이 λ™μ μœΌλ‘œ κ²°μ •λ˜κ³ , strict modeλ˜ν•œ this 바인딩에 영ν–₯을 μ€€λ‹€. thisλŠ” μ½”λ“œ μ–΄λ””μ—μ„œλ“  μ°Έμ‘°κ°€ κ°€λŠ₯ν•˜λ‹€. μ „μ—­μ—μ„œ μ‚¬μš©λ  경우 windowλ₯Ό μ°Έμ‘°ν•˜κ³ , ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ‚¬μš©λ  경우 μžκ°€ μ°Έμ‘°ν•œλ‹€. ν•˜μ§€λ§Œ strict mode 일 경우, 일반 ν•¨μˆ˜ λ‚΄λΆ€μ˜ thisμ—λŠ” undefinedκ°€ 바인딩 λœλ‹€. 일반 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” thisλ₯Ό μ‚¬μš©ν•  ν•„μš”κ°€ μ—†κΈ° λ•Œλ¬Έμ΄λ‹€.

// β—οΈμ „μ—­μ—μ„œ thisλŠ” μ „μ—­ 객체 window μ°Έμ‘°
console.log(this); // window

function square(num) {
	// β—οΈμΌλ°˜ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ thisλŠ” μ „μ—­ 객체 windowλ₯Ό 가리킨닀
	console.log(this); // window
	return num + num;
}

square(2);

const person = {
	name: 'Tia',
	getName(){
		// β—οΈλ©”μ„œλ“œ λ‚΄λΆ€μ—μ„œ thisλŠ” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 객체λ₯Ό 가리킨닀
		console.log(this); // {name: 'Tia', getName: f}
		return this.name;
	}
};

console.log(person.getName()); // Tia

function Person(name) {
	this.name = name;
	// β—οΈμƒμ„±μž ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ thisλŠ” μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€λ₯Ό 가리킨닀
	console.log(this); // Person {name: 'Tia', __proto__: { constructor: f}}
};

const me = new Person('Tia');

βœ”οΈ ν•¨μˆ˜ 호좜 방식과 this 바인딩

this 바인딩은 ν•¨μˆ˜ 호좜 방식, 즉 ν•¨μˆ˜κ°€ μ–΄λ–»κ²Œ ν˜ΈμΆœλ˜μ—ˆλŠ”μ§€μ— 따라 λ™μ μœΌλ‘œ κ²°μ •λœλ‹€. μ΄λ•Œ this λ°”μΈλ”©μ˜ κ²½μš°μ—λŠ” λ ‰μ‹œμ»¬ μŠ€μ½”ν”„μ™€ λ‹€λ₯΄κ²Œ ν•¨μˆ˜ 호좜 μ‹œμ μ— κ²°μ •λœλ‹€.

❓ 일반 ν•¨μˆ˜ 호좜

기본적으둜 thisμ—λŠ” μ „μ—­ 객체( global object )κ°€ 바인딩 λœλ‹€. λͺ¨λ“  ν•¨μˆ˜( μ „μ—­ ν•¨μˆ˜, 쀑첩 ν•¨μˆ˜, 콜백 ν•¨μˆ˜ 포함 )λŠ” 일반 ν•¨μˆ˜λ‘œ 호좜 μ‹œ ν•¨μˆ˜ λ‚΄λΆ€μ˜ thisμ—λŠ” μ „μ—­ 객체가 바인딩 λœλ‹€. μ΄λ•Œ λ§Œμ•½ strict mode 일 경우, 일반 ν•¨μˆ˜ λ‚΄λΆ€μ˜ thisμ—λŠ” undefinedκ°€ 바인딩 λœλ‹€.

function check () {
	console.log(`check's this: `, this); // window, if strict mode: undefined
	const checkAgain = () => {
		console.log(`checkAgain's this: `, this) // window, if strict mode: undefined
	}
	checkAgain();
}
check();

❓ λ©”μ„œλ“œ 호좜

λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 객체, 즉 λ©”μ„œλ“œ 호좜 μ‹œ λ©”μ„œλ“œ 이름 μ•žμ˜ λ§ˆμΉ¨ν‘œ μ—°μ‚°μž. μ•žμ— κΈ°μˆ ν•œ 객체가 바인딩 λœλ‹€. λ©”μ„œλ“œ λ‚΄λΆ€μ˜ thisλŠ” λ©”μ„œλ“œλ₯Ό μ†Œμœ ν•œ 객체가 μ•„λ‹Œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 객체에 바인딩 λœλ‹€.

const person = {
	name: 'Tia',
	getName() {
		// λ©”μ„œλ“œ λ‚΄λΆ€μ˜ thisλŠ” λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 객체에 바인딩
		return this.name;
	}
};

console.log(person.getName()); // Tia

const anotherPerson = {
	name: 'Anne',
};

anotherPerson.getName = person.getName;
console.log(anotherPerson.getName()); // Anne

const getName = person.getName;
console.log(getName()); // ''
// 일반 ν•¨μˆ˜λ‘œ 호좜된 getName ν•¨μˆ˜ λ‚΄λΆ€μ˜ this.name은 window.nameκ³Ό κ°™μŒ

❓ μƒμ„±μž ν•¨μˆ˜ 호좜

πŸ“ μƒμ„±μž ν•¨μˆ˜: 객체( μΈμŠ€ν„΄μŠ€ )λ₯Ό μƒμ„±ν•˜λŠ” ν•¨μˆ˜
일반 ν•¨μˆ˜μ™€ λ™μΌν•œ λ°©λ²•μœΌλ‘œ μƒμ„±μž ν•¨μˆ˜ μ •μ˜ ν›„ new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜μ—¬ μƒμ„±μž ν•¨μˆ˜λ₯Ό λ™μž‘ν•œλ‹€.
이 λ•Œ, new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜μ§€ μ•ŠμœΌλ©΄ 일반 ν•¨μˆ˜λ‘œ λ™μž‘ν•œλ‹€.

μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€κ°€ 바인딩 λœλ‹€.

❓ Function.prototype.apply/call/bind 호좜

apply, call, bindλŠ” Function.prototype의 λ©”μ„œλ“œμ΄λ‹€. 즉, λͺ¨λ“  ν•¨μˆ˜κ°€ 상속받아 μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

β–ͺ️ apply / call

apply와 call λ©”μ„œλ“œμ˜ 본질적 κΈ°λŠ₯은 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 것이닀. apply와 call λ©”μ„œλ“œλŠ” 첫 번째 인수둜 μ „λ‹¬ν•œ νŠΉμ • 객체λ₯Ό ν˜ΈμΆœν•œ ν•¨μˆ˜μ˜ this에 λ°”μΈλ”©ν•œλ‹€.

function thisBinding() {
	return this;
};

// this둜 μ‚¬μš©ν•  객체
const thisObj = { a: 1 };

console.log(thisBinding()); // window
console.log(thisBinding.apply(thisObj)); // {a: 1}
console.log(thisBinding.call(thisObj)); // {a: 1}

β–ͺ️ bind

bind λ©”μ„œλ“œμ˜ 본질적 κΈ°λŠ₯은 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šκ³  μ „λ‹¬ν•œ κ°’μœΌλ‘œ this 바인딩이 ꡐ체된 ν•¨μˆ˜λ₯Ό μƒˆλ‘­κ²Œ μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•˜λŠ” 것이닀.

function thisBinding() {
	return this;
};

// this둜 μ‚¬μš©ν•  객체
const thisObj = { a: 1 };

console.log(thisBinding.bind(thisObj)); // thisBinding
// bind λ©”μ„œλ“œλŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ§€λŠ” μ•ŠμœΌλ―€λ‘œ λͺ…μ‹œμ μœΌλ‘œ ν˜ΈμΆœν•΄μ•Ό 함
console.log(thisBinding.bind(thisObj)()); // { a: 1}

bindλŠ” λ©”μ„œλ“œμ˜ this와 λ©”μ„œλ“œ λ‚΄λΆ€μ˜ 쀑첩 ν•¨μˆ˜ λ˜λŠ” 콜백 ν•¨μˆ˜μ˜ thisκ°€ λΆˆμΌμΉ˜ν•˜λŠ” 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μœ μš©ν•˜κ²Œ μ‚¬μš©λœλ‹€.

const person = {
  name: 'Tia',
  getName(callback) {
    // bind λ©”μ„œλ“œλ‘œ callback ν•¨μˆ˜ λ‚΄λΆ€μ˜ this 바인딩을 전달
    setTimeout(callback.bind(this), 100);
  }
};

person.getName(function(){
  console.log(`Hi! my name is ${this.name}! πŸ‘‹`)
})

βœ… ν™”μ‚΄ν‘œ ν•¨μˆ˜μ™€ this

ν™”μ‚΄ν‘œ ν•¨μˆ˜λŠ” 일반적인 ν•¨μˆ˜μ™€λŠ” λ‹€λ₯΄κ²Œ μžμ‹ λ§Œμ˜ thisλ₯Ό μƒμ„±ν•˜μ§€ μ•ŠλŠ”λ‹€. λŒ€μ‹ , ν™”μ‚΄ν‘œ ν•¨μˆ˜κ°€ μ •μ˜λœ μ‹œμ μ— μ™ΈλΆ€ μŠ€μ½”ν”„μ˜ thisλ₯Ό μ°Έμ‘°ν•œλ‹€. μ΄λŠ” ν™”μ‚΄ν‘œ ν•¨μˆ˜ λ‚΄λΆ€μ˜ thisλŠ” μƒμœ„ μŠ€μ½”ν”„μ˜ this와 λ™μΌν•œ 값을 κ°€μ§€λŠ” 것을 μ˜λ―Έν•œλ‹€. λ”°λΌμ„œ μ „μ—­ μŠ€μ½”ν”„μ—μ„œ ν™”μ‚΄ν‘œ ν•¨μˆ˜μ™€ thisλ₯Ό μ‚¬μš©ν•  경우, μ°Έμ‘°ν•  λ‹€λ₯Έ 값이 μ—†μœΌλ―€λ‘œ μ „μ—­ 객체, 즉 windowλ₯Ό μ°Έμ‘°ν•œλ‹€.

0개의 λŒ“κΈ€