call, apply and bind

What is call, apply and bind?

javascript

2018-04-14


๊ฐœ์ธ์ ์ธ ๊ณต๋ถ€ ๋…ธํŠธ๋กœ, ์˜ค๋ฅ˜๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1. apply

call๊ณผ apply๋Š” ๊ธฐ๋Šฅ โ€” ํ•จ์ˆ˜ ํ˜ธ์ถœํ•˜๊ธฐ โ€” ์€ ๊ฐ™๊ณ  ๋ฐ›๋Š” ์ธ์ž๋งŒ ๋‹ค๋ฅด๋‹ค. ๋‘˜๋‹ค this ํ‚ค์›Œ๋“œ๋ฅผ ํŠน์ • ๊ฐ์ฒด์— ๋ฐ”์ธ๋”ฉ ํ•˜๋Š” ๋ฉ”์†Œ๋“œ์ด๋‹ค.

func.apply(thisArg, argsArray)
  • ์ฒซ๋ฒˆ์งธ ์ธ์ž๋Š” this๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ๊ฐ์ฒด, ๋‘๋ฒˆ์งธ ์ธ์ž๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ์ธ์ž๋“ค์˜ ๋ฐฐ์—ด์ด๋‹ค.
var Person = function(name, age) {
  this.name = name
  this.age = age
}

var me = {}

Person.apply(me, ["Jane", "15"])
  • ์ด๋ ‡๊ฒŒ ๋นˆ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“  ๋’ค, ์ƒ์„ฑ์ž๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  Person ๊ฐ์ฒด์— prototype์„ ์—ฐ๊ฒฐํ•˜์—ฌ ์ƒ์†ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ Person.prototype์œผ๋กœ ์—ฐ๊ฒฐ๋œ ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒƒ์ผ ๋ฟ์ด๋‹ค.

2. call

apply์™€ ๊ธฐ๋Šฅ์€ ๊ฐ™๋‹ค. ๋‹จ, ๋‘๋ฒˆ์งธ ์ธ์ž๋ฅผ ๋ฐฐ์—ด์— ๋„ฃ์ง€ ์•Š๊ณ  ๊ทธ๋Œ€๋กœ ๋„˜๊ฒจ์ฃผ๋ฉด ๋œ๋‹ค.

Person.call(me, "Jane", "15")
  • this๋Š” method๊ฐ€ ์•„๋‹ˆ๋ผ caller์— ์˜ํ•ด ๊ฒฐ์ •๋œ๋‹ค. obj.method()์™€ method.call(obj)๋Š” ๊ฐ™๋‹ค๋Š” ๊ฒƒ์—์„œ ์œ ์ถ”ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘‰ ์–ธ์ œ ์‚ฌ์šฉํ• ๊นŒ?

  • apply์™€ call ๋ชจ๋‘ NodeList ๋“ฑ๊ณผ ๊ฐ™์€ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์— ๋ฐฐ์—ด ๋ฉ”์†Œ๋“œ๋ฅผ ์“ฐ๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
// ์ด๋ ‡๊ฒŒ
Array.prototype.slice.apply(pseudoArray)

3. bind

  • bind๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝœ๋ฐฑ์„ ํ˜ธ์ถœํ•  ๋•Œ, ๋งฅ๋ฝ์— ์ƒ๊ด€์—†์ด ํŠน์ • this์— ๋Œ€ํ•˜์—ฌ(ํŠน์ • ๊ฐ์ฒด์— ๋Œ€ํ•˜์—ฌ) ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.
  • this์˜ ๋งฅ๋ฝ์€ ์–ด๋””์—์„œ ์“ฐ์ด๋Š๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์–ธ์ œ ์“ฐ์ด๋“ ์ง€ ๊ฐ™์€ ๋™์ž‘์„ ๊ธฐ๋Œ€ํ•  ๋•Œ ์ฃผ๋กœ ์“ฐ์ธ๋‹ค.

๐Ÿ‘‰ React์—์„œ bind()

class Toggle extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isToggleOn: true };

    // This binding is necessary to make `this` work in the callback
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    this.setState(prevState => ({
      isToggleOn: !prevState.isToggleOn
    }));
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        {this.state.isToggleOn ? 'ON' : 'OFF'}
      </button>
    );
  }
}
  • button์˜ onClick์˜ ์ฝœ๋ฐฑ์œผ๋กœ this.handleClick์„ ๋ถˆ๋Ÿฌ์˜ฌ ๋•Œ, this๋Š” undefined๊ฐ€ ๋œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํด๋ž˜์Šค ๋ฉ”์†Œ๋“œ๋Š” ๋””ํดํŠธ๋กœ ๋ฐ”์ธ๋”ฉ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋”ฐ๋ผ์„œ this.handleClick = this.handleClick.bind(this); ์ด๋ ‡๊ฒŒ ๋ฉ”์†Œ๋“œ์— this(Toggle)์„ ๋ฐ˜๋“œ์‹œ ๋ฐ”์ธ๋”ฉํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.
  • ๋‹ค๋ฅธ ๋ฐฉ๋ฒ• ๐Ÿ‘‡

    • *babel ํ”Œ๋Ÿฌ๊ทธ์ธ transform-class-properties์ด ๋””ํดํŠธ ๋ฐ”์ธ๋”ฉ์„ ์ง€์›ํ•˜๋ฉฐ, create-react-app์—์„œ๋„ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.
    • ๋˜๋Š” onClick={(e) => this.handleClick(e)}์™€ ๊ฐ™์ด arrow function ์•ˆ์—์„œ ์“ธ์ˆ˜๋„ ์žˆ๋‹ค.