이 글은 this 에서 넘어온 글입니다.
https://daunje0.tistory.com/manage/newpost/84?type=post&returnURL=ENTRY
var a = 10;
var obj = {
a: 20,
b: function () {
console.log(this.a); // 20 (메서드로써 호출했으므로 obj 객체가 this이다)
function c() {
console.log(this.a); // 10 (함수로써 호출했으므로 전역 인스턴스 this)
}
c();
}
}
obj.b();
call, apply, 그리고 bind는 함수를 다룰 때 사용되는 메소드입니다.
이 세 가지 메소드는 함수를 호출하거나 함수의 this 값을 바인딩하는 데 사용됩니다.
참고로 node.js 에서는 브라우저 환경과는 조금 다르다
1. Node.js에는 window 객체 대신 global 객체 있는데,
2. Node.js에서 var로 선언된 변수는 모듈 스코프에 속하며, 자동으로 global 객체의 속성이 되지 않는다.
3. 그래서 function c 의 로그는 uindefined 가 나오며 위와 같은 10의 결과가 나오게 하려면
global.a = 10; // 명시적으로 global 객체에 a를 할당 해야 같은 결과가 나온다
var obj = {
a: 20,
b: function () {
console.log(this.a); //20
function c() {
console.log(this.a); //10
}
c();
}
}
obj.b();
다시 본론으로 돌아가자면,
우회법 1 : this 를 변수에 담기
먼저 실행 컨텍스트 페이지에서 다뤘던 scope chaining 그림을 한번 더 보고 아래의 코드를 봐보자
var a = 10;
var obj = {
a: 20,
b: function () {
var _this = this;
console.log(this.a); // 20 (메서드로써 호출했으므로 obj 객체가 this이다)
function c() {
console.log(_this.a); // 20
}
c();
}
}
obj.b();
레거시 프로젝트를 보면 위처럼 변수에 this 를 담아 사용하는 방식을 쓰는 경우를 개인적으론 가장 많이 봤다
_this는 function C 안에 없기 때문에 그 상위 스코프인 b:fuction () {} 에서 _this를 사용하게 되며 ( scope chaining ),
이렇게 변수에 this 를 담으면 아래 그림처럼 _this 는 obj 객체를 가르키는 것을 알 수 있다
우회법 2: 화살표 함수 사용하기
var a = 10;
var obj = {
a: 20,
b: function () {
console.log(this.a); // 20 (메서드로써 호출했으므로 obj 객체가 this이다)
const c = () => console.log(this.a); // 20
c();
}
}
obj.b();
일반 함수는 자신만의 this 컨텍스트를 생성하고, 호출 방식에 따라 this가 결정되지만
화살표 함수는 자신의 this 바인딩을 생성하지 않고, 렉시컬 스코프의 this를 사용한다 .
(즉, 상위 스코프의 this를 그대로 사용)
const obj = {
name: "테스트",
regularMethod: function() {
console.log(this.name);
setTimeout(function() {
console.log(this.name); // undefined (Node.js) 또는 "" (브라우저)
}, 100);
setTimeout(() => {
console.log(this.name); // "테스트"
}, 100);
}
};
obj.regularMethod();
우회법 3: 자바스크립트 내장함수 사용하기(call, apply, bind)
function a(x, y ,z) {
console.log(this, x, y, z);
}
var b = {
bb: 'bbb'
}
a.call(b, 1, 2, 3)
a.apply(b, [1, 2, 3])
var c = a.bind(b)
c(1, 2, 3)
var d = a.bind(b, 1, 2)
d(3)
결과 값은 넷 다 동일하게 나온다
call:
call은 함수를 즉시 실행하면서 첫 번째 인자로 this를 바인딩할 객체를 전달한다.
그 뒤의 인자들은 함수의 매개변수로 전달된다.
function 인사(greeting) {
console.log(greeting + ' ' + this.name);
}
const 사람 = { name: '영희' };
인사.call(사람, '안녕하세요'); // 출력: 안녕하세요 영희
apply:
call 메소드와 유사하며 차이는 파라미터를 배열로 전달한다는 점이다
function 소개(나이, 직업) {
console.log(`제 이름은 ${this.name}이고, ${나이}살이며, ${직업}입니다.`);
}
const 사람 = { name: '철수' };
소개.apply(사람, [25, '개발자']); // 출력: 제 이름은 철수이고, 25살이며, 개발자입니다.
bind:
bind 메소드는 새로운 함수를 생성하며,
이 함수의 this는 bind의 첫 번째 인자로 영구적으로 바인딩된다.
바인딩된 함수는 나중에 호출할 수 있다.
function 자기소개() {
console.log(`안녕하세요, 저는 ${this.name}입니다.`);
}
const 사람1 = { name: '민수' };
const 사람2 = { name: '지영' };
const 민수소개 = 자기소개.bind(사람1);
const 지영소개 = 자기소개.bind(사람2);
민수소개(); // 출력: 안녕하세요, 저는 민수입니다.
지영소개(); // 출력: 안녕하세요, 저는 지영입니다.
요약하자면,
1. call과 apply는 함수를 즉시 실행한다.
2. bind는 새로운 함수를 반환하며, 이 함수는 나중에 실행할 수 있다.
3 .call은 인자를 개별적으로 전달하고, apply는 인자를 배열로 전달한다.
call
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
apply
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
bind
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
'JavaScript > AboutJS' 카테고리의 다른 글
[JavaScript ]CommonJS 모듈 ES 모듈 차이 (0) | 2024.08.26 |
---|---|
[JavaScript] Closure (클로져) (0) | 2024.08.23 |
[JavaScript] 이벤트 루프란? (0) | 2024.08.21 |
[JavaScript] This 를 판단하는 기준 (0) | 2024.08.18 |
[JavaScript] 실행 컨텍스트 ( Execution Context ) (0) | 2024.04.24 |