bind 하나만 알면 apply, call 거저먹음!!

낭만개발자·2021년 11월 16일
1

JavaScript

목록 보기
8/14

bind(feat. Node에서 this)

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이 출력값으로 뜬다.

글 참조 : https://kamang-it.tistory.com/entry/JavaScript07this-this%EB%B0%94%EC%9D%B8%EB%93%9C%ED%8E%B8bindcallapply

Node에서 this

  1. Node에서 (함수 안이 아닌) 그냥 전역에서 this를 로그로 찍으면 module.exports 이다. 파일을 모듈로 사용할 수 있게 해주는 객체이다.

즉 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

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

출처:
https://kamang-it.tistory.com/entry/JavaScript07this-this%EB%B0%94%EC%9D%B8%EB%93%9C%ED%8E%B8bindcallapply

profile
낭만닥터와 슬의를 보고 저런 개발자가 되어야 겠다고 꿈꿔봅니다.

0개의 댓글