js에서 this는 변동이 심해서 상당히 까다로운데(아래 node서 this 참조), 그래서 this를 고정시키는 방법 이 binding이다. 즉 바인드 거는 함수에게 "함수야! 앞으로 this를 사용할땐 파라미터로 내가 넣어주는 객체를 사용해!" 라고 명령 하는 함수이다.
function sum(num) {
return num + this.num1 + this.num2;
}
console.log(sum(100));
위 코드에서 this는 케이스에 따라 다양하게 된다. 브라우저? node? 메서드? 다 다르게 나옴
function sum(num) {
return num + this.num1 + this.num2;
}
var myObj = {num1:20, num2: 3};
var customSum = sum.bind(myObj);
console.log(customSum(5));
// 출력값 28
sum.bind(myObj)
란 말은 풀어쓰자면
"myobj 객체에 sum 함수를 바인딩!" =
var myObj =
{ num1:20,
num2:3,
sum : function (num) {
return num + this.num1 + this.num2;
}
}; //여기서 this는 상위 객체인 myObj {}를 가리킨다.
이라는 뜻이므로 즉 아래 명령과 같다.
"sum 함수야 this를 사용할땐 무조건 myObj 객체를 참고해!" 라고 명령하는 함수가 bind() 다 따라서 sum함수내에서 this가 myObj를 참조하니깐
sum 함수 계산이 return 5 + 20 + 3
이 되므로 28이 출력값으로 뜬다.
즉 node에서 console.log(this)
를 찍으면 브라우저처럼 window가 나오는게 아니라 {}
빈 객체가 나온다. window와 document는 Node에 없는 객체 이므로. 두 객체는 브라우저 런타임에서 넣어주는 개체이기 때문이다.
예로 아래 로그를 찍으면
console.log(this, module.exports, exports);
console.log(this === module.exports);
console.log(this === exports);
console.log(module.exports === exports);
//결과
{} {} {}
true
true
true
이렇게 나오는데 즉 module.exports = exports = this 인 셈이다.
전역환경에선 위처럼 3위일체 이고, 함수 선언문 안의 this는 global이다.
function a() {
console.log('a', this === exports, this === global);
}
const b = () => {
console.log('b', this === exports);
};
a();
b();
//결과
a false true
b true
Node의
전역환경에서의 this => module.exports,
함수 선언문 안의 this => global
화살표 함수의 this => (this가 상위 환경의 this를 물려받기 때문에) module.exports
원 글내용 : https://www.zerocho.com/category/NodeJS/post/5b67e8607bbbd3001b43fd7b
call, apply는 bind만 시키는게 아니라 실행까지도 같이 한다는 점이다.
둘다 기능은 똑같다. 바인딩 하고 실행하고.
차이점은 파라미터가 다른데
.call() : 호출된함수.call(this지정할 객체, 호출된함수에 넣을 파라미터 1, 파라미터 2... )
.apply() : 호출된함수.apply(this지정할 객체, [호출된함수에 넣을 파라미터 1, 파라미터 2... ])
이런식으로 call은 파라미터를 개별적으로 넣어주고, apply는 배열로 넣어준다.
(call만 써도 충분할듯)
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
info(v, w) {
console.log(`x : ${this.x} y: ${this.y}, v: ${v}, w: ${w}`);
}
}
let point = new Point(10, 20);
point.info(1, 2);
let customPoint = { x: 100, y: 200 };
point.info.call(customPoint, 20, 30);
point.info.apply(customPoint, [2, 3])
결과
파일 소스:https://replit.com/@heedaelee/JScall-apply-study#index.js