this
키워드는 호출 시 함수에 바인딩된 객체의 값을 나타냅니다. 즉, 함수가 메서드로 호출되는지, 독립형 함수로 호출되는지, 생성자로 호출되는지에 따라 값이 다릅니다.
함수가 호출되면 함수가 포함된 객체에 대한 참조로 this
키워드의 인스턴스를 백그라운드에서 만들고, 범위 내에서 함수와 함께 정의된 속성과 메서드에 액세스할 수 있도록 합니다.
this
를 사용하는 것은 const
로 선언된 변수를 사용하는 것과 몇 가지 면에서 유사합니다. 상수와 마찬가지로 this
는 삭제할 수 없으며 값을 재할당할 수 없지만 this
키워드가 포함된 객체의 메서드와 속성은 변경할 수 있습니다.
전역 결합
함수 또는 객체의 컨텍스트 외부에서 this
는 대부분의 JavaScript 환경에서 전역 객체에 대한 참조인 globalThis
속성을 참조합니다. 웹브라우저에서 실행되는 스크립트의 컨텍스트에서 전역 객체는 window
객체입니다.
this;
> Window {0: Window, window: Window, self: Window, document: document, name: '', location: Location, ...}
Node.js에서 globalThis
는 global
객체입니다.
$ node
Welcome to Node.js v20.10.0.
Type ".help" for more information.
> this
<ref *1> Object [global] {
...
}
엄격 모드 외부에서 this
는 독립형 함수 내의 전역 객체도 참조합니다. 상위 Window
가 이러한 함수를 효과적으로 '소유'하는 객체이기 때문입니다.
function myFunction() {
console.log( this );
}
myFunction();
> Window {...}
(function() {
console.log( this );
}());
> Window {...}
엄격 모드를 사용하는 경우 this
는 독립형 함수 내에서 undefined
값을 갖습니다.
(function() {
"use strict";
console.log( this );
}());
> undefined
엄격 모드가 도입되기 전에는 this
의 null
또는 undefined
값이 전역 객체 참조로 대체되었습니다. 이 기존 동작으로 인해 전역 바인딩이 '기본 바인딩'이라고 표시되는 경우가 있습니다.
암시적 결합
함수가 객체의 메서드로 호출되면 해당 메서드 내의 this
인스턴스가 메서드가 포함된 객체를 참조하여 그 옆에 있는 메서드와 속성에 액세스할 수 있습니다.
let myObject = {
myValue: "This is my string.",
myMethod() {
console.log( this.myValue );
}
};
myObject.myMethod();
> "This is my string."
this
의 값은 함수와 이를 래핑하는 객체가 정의되는 방식에 따라 달라지는 것처럼 보일 수 있습니다. 대신 this
값의 컨텍스트는 현재 실행 컨텍스트입니다. 이 경우 실행 컨텍스트는 myObject
객체가 myMethod
메서드를 호출하는 것이므로 myObject
는 this
의 값입니다. 이는 이전 예시의 맥락에서는 기술적인 문제로 보일 수 있지만 this
를 더 고급으로 사용하려면 염두에 두어야 하는 중요한 구분입니다.
일반적으로 주변 코드에 특정 구조가 있을 것으로 예상하지 않는 방식으로 this
를 사용하세요. 이 규칙의 예외는 ES5 화살표 함수입니다.
화살표 함수의 this
화살표 함수에서 this
는 문법적 괄호로 묶인 환경의 바인딩으로 확인됩니다. 즉, 화살표 함수의 this
는 해당 함수의 가장 가까운 닫는 컨텍스트에 있는 this
값을 참조합니다.
let myObject = {
myMethod() { console.log( this ); },
myArrowFunction: () => console.log( this ),
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myMethod();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
myObject.myArrowFunction();
> Window {...}
이전 예에서 myObject.myMethod()
는 myObject
를 해당 메서드를 '소유'하는 객체로 로깅하지만 myObject.myArrowFunction()
는 globalThis
(또는 undefined
)를 반환합니다. 화살표 함수 내부의 this
인스턴스가 대신 가장 높은 닫는 범위를 참조하기 때문입니다.
다음 예에서 myEnclosingMethod
는 실행 시 이를 포함하는 객체에 화살표 함수를 만듭니다. 이제 화살표 함수 내의 this
인스턴스는 해당 화살표 함수를 포함하는 메서드인 래핑 환경 내의 this
값을 참조합니다. myEnclosingMethod
내의 this
값이 myObject
를 참조하므로 화살표 함수를 정의한 후에는 화살표 함수 내의 this
도 myObject
를 참조합니다.
let myObject = {
myMethod() { console.log( this ); },
myEnclosingMethod: function () {
this.myArrowFunction = () => { console.log(this) };
}
};
myObject.myEnclosingMethod();
myObject.myArrowFunction();
> Object { myMethod: myMethod(), myArrowFunction: myArrowFunction() }
명시적 바인딩
암시적 결합은 this
를 사용하는 대부분의 사용 사례를 처리합니다. 그러나 가정된 컨텍스트 대신 특정 실행 컨텍스트를 나타내기 위해 this
값이 필요할 수 있습니다. 약간 오래되었지만 설명을 위한 예는 setTimeout
의 콜백 함수 내에서 this
를 사용하는 것입니다. 이 콜백에는 고유한 실행 컨텍스트가 있기 때문입니다.
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
myObject.myMethod();
> "This is my string."
setTimeout( myObject.myMethod, 100 );
> undefined
setTimeout
의 이 특정 단점은 이후 다른 기능으로 해결되었지만, this
'손실'과 관련된 유사한 문제는 이전에 의도한 컨텍스트의 범위 내에서 this
값에 대한 명시적 참조를 만들어 해결되었습니다. 기존 코드베이스에서 that
, self
, _this
와 같은 식별자를 사용하여 this
인스턴스가 변수에 할당되는 경우가 있습니다. 전달된 this
값이 포함된 변수의 일반적인 식별자 규칙입니다.
call()
, bind()
또는 apply()
메서드를 사용하여 함수를 호출하면 this
은 호출되는 객체를 명시적으로 참조합니다.
let myFunction = function() {
console.log( this.myValue );
}
let myObject = {
"myValue" : "This is my string."
};
myFunction.call( myObject );
> "This is my string."
var myObject = {
myString: "This is my string.",
myMethod() {
console.log( this.myString );
}
};
setTimeout( myObject.myMethod.bind( myObject ), 100 );
> "This is my string."
명시적 결합은 암시적 결합에서 제공한 this
값을 재정의합니다.
let myObject = {
"myValue" : "This string sits alongside myMethod.",
myMethod() {
console.log( this.myValue );
}
};
let myOtherObject = {
"myValue" : "This is a string in another object entirely.",
};
myObject.myMethod.call( myOtherObject );
> "This is a string in another object entirely."
this
값을 undefined
또는 null
로 설정하는 방식으로 함수가 호출되면 엄격 모드 외부에서 해당 값이 globalThis
로 대체됩니다.
let myFunction = function() {
console.log( this );
}
myFunction.call( null );
> Window {...}
마찬가지로 함수가 this
에 원시 값을 제공하는 방식으로 호출되면 이 값은 엄격 모드 외부에서 원시 값의 래퍼 객체로 대체됩니다.
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> Number { 10 }
엄격 모드에서는 전달된 this
값이 원시 값, null
또는 undefined
값이더라도 어떤 방식으로도 객체로 강제 변환되지 않습니다.
"use strict";
let myFunction = function() {
console.log( this );
}
let myNumber = 10;
myFunction.call( myNumber );
> 10
myFunction.call( null );
> null
new
바인딩
클래스가 new
키워드를 사용하여 생성자로 사용되면 this
은 새로 생성된 인스턴스를 참조합니다.
class MyClass {
myString;
constructor() {
this.myString = "My string.";
}
logThis() {
console.log( this );
}
}
const thisClass = new MyClass();
thisClass.logThis();
> Object { myString: "My string." }
마찬가지로 new
를 사용하여 호출된 생성자 함수 내의 this
값은 생성 중인 객체를 참조합니다.
function MyFunction() {
this.myString = "My string.";
this.logThis = function() {
console.log( this );
}
}
const myObject = new MyFunction();
myObject.logThis();
> Object { myString: "My string.", logThis: logThis() }
이벤트 핸들러 바인딩
이벤트 핸들러 컨텍스트에서 this
의 값은 이를 호출하는 객체를 참조합니다. 이벤트 핸들러의 콜백 함수 내에서 this
는 핸들러와 연결된 요소를 참조합니다.
let button = document.querySelector( "button" );
button.addEventListener( "click", function( event ) { console.log( this ); } );
사용자가 이전 스니펫의 button
와 상호작용할 때 결과는 <button>
자체가 포함된 요소 객체입니다.
> Button {}
화살표 함수가 이벤트 리스너 콜백으로 사용되면 가장 가까운 외부 실행 컨텍스트에서 this
값이 다시 제공됩니다. 최상위 수준에서 이는 이벤트 핸들러 콜백 함수 내의 this
가 globalThis
임을 의미합니다.
let button = document.querySelector( "button" );
button.addEventListener( "click", ( event ) => { console.log( this ); } );
> undefined
다른 객체와 마찬가지로 call()
, bind()
또는 apply()
메서드를 사용하여 이벤트 리스너의 콜백 함수를 참조하면 this
는 객체를 명시적으로 참조합니다.
let button = document.querySelector( "button" );
let myObject = {
"myValue" : true
};
function handleClick() {
console.log( this );
}
button.addEventListener( "click", handleClick.bind( myObject ) );
> Object { myValue: true }
이해도 확인
웹브라우저에서 실행되는 스크립트의 경우 함수 외부 또는 객체 컨텍스트에서 사용될 때 this
가 참조하는 전역 객체는 무엇인가요?
window
객체browser
객체undefined
객체