2025. 4. 5. 12:37ㆍCoding Study/Javascript
1. 전역 공간에서의 this
1) 브라우저 환경에 this
- 전역 공간에서 this 는 window 이다.
console.log(this) // window 객체
console.log(window) // window 객체
console.log(this === window) //ture
2) node.js 환경에 this
- 코어 자바스크립트에서는 node.js 환경에서 this 는 global 이라고 나와있는데,
vscode 의 node.js 환경에서 실행 시 전역에서의 this 가 {} 로 출력이 되었다.
- 검색 결과 vscode 의 node.js 환경에서의 전역은 module.experts 이라고 한다.
console.log(this) // {}
console.log(global) // global 객체
console.log(this === global) //false
- 확인결과 전역에서 this 와 module.exports 비교 시 true 라고 나왔다.
- 함수 내부에서는 this 가 global 로 출력 된다.
console.log(module.exports === this); //true
function a() {
console.log(this); // global 객체
}
a();
< Node.js 와 브라우저의 전역공간에서의 this 가 달라 아래의 예제 부터는 크롬 브라우저 환경에서 진행 >
2. 메서드에서의 this
1) 함수로서의 호출과 메서드에서의 호출
함수에서의 호출과 메서드에서의 호출 구분은 함수 앞에 점의 여부로 구분 가능
앞에 점이 없으면 함수로서 호출
앞에 점이있으면 메서드로서 호출 (점대신 대괄호 표기법도 동일함)
const func = function () {
console.log(this);
};
func(); // Window
const obj = {
method: func,
};
obj.method(); // { method: f }
obj['method'](); // { method: f }
2) 메서드 내부에서 this
함수를 실행 하는 당시의 주변환경은 중요하지 않고, 해당 함수를 호출하는 구문앞에 점 또는 대괄호 표기가
있는지 없는지에 따라 this를 바인딩하는 주체가 달라진다.
const obj1 = {
outer: function () {
console.log(this); // obj1 { outer : f }
const innerFunc = function () {
console.log(this); // window
// obj2 { innerMethod:f }
};
innerFunc();
const obj2 = {
innerMethod: innerFunc,
};
obj2.innerMethod();
},
};
obj1.outer();
3) 함수 내부에서의 this 후회 방법
함수 호출 전 this 객체를 변수에 할당하여 적용.
const obj = {
outer: function () {
console.log(this); // obj { outer: f }
var innerFunc1 = function () {
console.log(this); // Window { ... }
};
innerFunc1();
const self = this; //<--- 변수 할당
const innerFunc2 = function () {
console.log(self); // obj { outer: f }
};
innerFunc2();
},
};
obj.outer();
3) this 를 바인딩 하지 않는 함수
arrow function(화살표함수) 는 실행컨텍스트를 생성할 때 this 바인딩 과정 자체가 빠지게 되어,
상위 스코프의 this 를그대로 활용 가능
const obj = {
outer: function () {
console.log(this); // obj { outer: f }
const innerFunc = () => {
console.log(this); // obj { outer: f }
};
innerFunc();
},
};
obj.outer();
4) 콜백 함수에서의 this
- forEach 메서드에서는 this 가 전역 객체 window
const obj1 = [1, 2, 3, 4, 5];
obj1.forEach((item) => console.log(this)); //window 객체 5번 출력
- setTimeout 에서도 this 가 전역 객체 window
setTimeout(function () {
console.log(this);
}, 300); // window
- 클릭 이벤트에서는 this 가 클릭 이벤트 객체를 출력
document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector("#a").addEventListener("click", function (e) {
console.log(this, e);
}); // 클릭시 <button id="a">클릭</button> 객체 출력
함수 A의 제어권을 다른함수(또는 메서드)B 에게 넘겨주는 경우 함수 A를 콜백함수
함수 A는 함수 B의 내부 로직에 따라 실행
이때 this 도 함수 B의 내부 규칙에 따라 결정
그러므로 함수 B가 this 를 무엇으로 할지 결정하며, 특별히 정의하지 않은 경우에는 기본적으로 전역객체를 바라본다.
3. 명시적으로 this 를 바인딩 하는 방법
1) call 메서드
Call 메서드는 호출 주체 함수에 첫번째 인자를 this 로 바인딩하여 실행 하고, 이후의 변수를 호출 한 함수의 매개 변수로 전달함.
func = function (x, y, z) {
return `${this.name} / ${x * y * z};`;
};
obj = {
name: "이름",
};
//obj 객체를 this 로 바인딩
console.log(func.call(obj, 5, 2, 3)); // 이름 / 30
// 첫번째 인자에 객체를 바로 넣어도 가능
console.log(func.call({ name: "이름" }, 5, 2, 3)); // 이름 / 30
2) apply 메서드
apply 메서드는 결과값이 call 메서드와 동일하지만 this 바인딩 하는 첫번째 인자 뒤의 변수를 배열로 넣어야 한다.
func = function (x, y, z) {
return `${this.name} / ${x * y * z};`;
};
obj = {
name: "이름",
};
//obj 객체를 this 로 바인딩
console.log(func.apply(obj, [5, 2, 3])); // 이름 / 30
// 첫번째 인자에 객체를 바로 넣어도 가능
console.log(func.apply({ name: "이름" }, [5, 2, 3])); // 이름 / 30
3) bind 메서드
bind 메서드는 위의 call 과 apply 와 달리 함수를 반환
그래서 함수를 변수로 받아서 다시 인자를 넣어 출력 하는 방식
bind 메서드의 첫번째 인자는 call 과 apply 와 동일하게 this를 바인딩할 주체
그 뒤의 3개 인자중 작성하는 갯수 만큼 고정인자로 들어가게 된다.
func = function (x, y, z) {
return `${this.name} / ${x * y * z};`;
};
obj = {
name: "이름",
};
// bind 첫인자 이후 작성에 따른 결과값
// 인자 작성 x
const bindfunc = func.bind(obj);
console.log(bindfunc(5, 2, 5)); // 이름 / 50
// 인자 1개 작성시
const bindfunc1 = func.bind(obj, 5);
console.log(bindfunc1(2, 5)); // 이름 / 50
// 인자 2개 작성시
const bindfunc2 = func.bind(obj, 5, 2);
console.log(bindfunc2(5)); // 이름 / 50
// 인자 3개 작성시
const bindfunc3 = func.bind(obj, 5, 2, 5);
console.log(bindfunc3()); // 이름 / 50
<기타>
addEventListener 로 Click 이벤트 생성 시 사용되는 함수에 bind메서드를 사용하게 되면 event 객체가 뒤로 밀려나서 3번째 인자로
자동 전달됨.
const fruits = ["apple", "banana", "peach"];
const $ul = document.createElement("ul");
const alertFruit = function (fruit, event) { // 자동으로 전달된 event 객체
console.log("your choice is " + fruit);
console.log(event); // 클릭 시 출력됨
};
fruits.forEach(function (fruit) {
const $li = document.createElement("li");
$li.innerText = fruit;
$li.addEventListener("click", alertFruit.bind(null, fruit)); // event 객체는 3번째 인자로 자동전달
$ul.appendChild($li);
});
document.body.appendChild($ul);'Coding Study > Javascript' 카테고리의 다른 글
| 실행 컨택스트 (0) | 2025.04.23 |
|---|---|
| 자바스크립트 var, let, const 키워드 (0) | 2025.04.18 |
| bind 메서드 (0) | 2025.03.31 |
| 객체의 Destructuring (구조 분해) (0) | 2025.03.18 |
| 배열의 Destructuring (구조 분해) (0) | 2025.03.18 |