๐Ÿ“ ๊ฐœ๋ฐœ

console.log ์œ ํ‹ธ์„ ๋งŒ๋“ค๋‹ค๊ฐ€ bind ํ•จ์ˆ˜์˜ ๋™์ž‘ ๋ฐฉ์‹ ํŒŒํ—ค์ณ๋ณด๊ธฐ

2026-01-21


ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด console.log๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ๋Š”๋ฐ์š”. ์ €๋Š” console.log๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋งˆ๋‹ค ์•ฝ๊ฐ„์˜ ๋ถˆํŽธํ•œ ์ ์ด ์žˆ์–ด์„œ console.log์šฉ ์œ ํ‹ธ์„ ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ ๋ฐฉ์‹์—๋„ ๋ถˆํŽธํ•œ ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ bind๋ฅผ ํ™œ์šฉํ•ด์„œ ๋กœ๊ทธ ์œ ํ‹ธ์„ ๊ฐœ์„ ํ•˜๋‹ˆ ๋ฌธ์ œ์ ์ด ํ•ด๊ฒฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์€ ์ด๋Ÿฐ ์ œ ๊ฒฝํ—˜์„ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

console.log๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ถˆํŽธํ•œ ์ 

ํ”„๋กœ์ ํŠธ์— no-console๊ฐ™์€ ๋ฆฐํŠธ ๊ทœ์น™์ด ์„ ์–ธ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ console.log๋ฅผ ์ฝ”๋“œ๋ฒ ์ด์Šค์— ์ถ”๊ฐ€ํ•˜๋ฉด no-console๊ฐ™์€ ๊ทœ์น™ ๋•Œ๋ฌธ์— ์—๋Ÿฌ๋‚˜ warning์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ๋ฆฐํŠธ ๊ทœ์น™์„ ์ „๋ถ€ ๋น„ํ™œ์„ฑํ™”ํ•˜๋ฉด, ํ”„๋กœ๋•์…˜ ์ฝ”๋“œ์— ๋กœ๊ทธ๊ฐ€ ๊ทธ๋Œ€๋กœ ํฌํ•จ๋œ ์ฑ„๋กœ ์˜ฌ๋ผ๊ฐ€๋Š” ์‹ค์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌผ๋ก  ์ด ๋ฌธ์ œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฐœ๋ฐœ ๋ชจ๋‘์—์„œ๋งŒ ๋กœ๊ทธ๊ฐ€ ํ™œ์„ฑํ™”๋˜๋„๋ก ๋ถ„๊ธฐ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์„œ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋กœ๊ทธ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ชจ๋“  ์œ„์น˜์—์„œ ์กฐ๊ฑด๋ฌธ์„ ์ž‘์„ฑํ•ด์•ผ ํ•ด์„œ ๊ฐ€๋…์„ฑ์ด ์ €ํ•˜๋œ๋‹ค๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

if (IS_LOCAL) {
  log.info('debug log');
}

์ฒ˜์Œ์— ๊ณ ์•ˆํ–ˆ๋˜ ํ•ด๊ฒฐ์ฑ…๊ณผ ํ•œ๊ณ„

์ €๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ณดํ†ต์€ ๋กœ๊ทธ ์ „์šฉ ์œ ํ‹ธ์„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

// log.ts
const noop = () => {};
 
export const log = {
  error: (...args) => IS_LOCAL ? console.error(...args) : noop(),
  info: (...args) => IS_LOCAL ? console.log(...args) : noop(),
};

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋ฆฐํŠธ ๊ทœ์น™ ๋ฌด์‹œ, ๊ฐœ๋ฐœ๋ชจ๋“œ ๋ถ„๊ธฐ๋„ ์œ ํ‹ธ์—์„œ๋งŒ ์ฒ˜๋ฆฌํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์—์„œ ๋งํ•œ ๋ฌธ์ œ์ ์ด ๋ชจ๋‘ ํ•ด๊ฒฐ๋œ ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ, ์น˜๋ช…์ ์ธ ๋‹จ์ ์ด ํ•˜๋‚˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ”๋กœ log ์œ ํ‹ธ ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ํ•˜๋‚˜์˜ JavaScript ํ•จ์ˆ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ํ˜ธ์ถœ ์‹œ ์ƒˆ๋กœ์šด ์Šคํƒ ํ”„๋ ˆ์ž„์ด ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋กœ๊ทธ ํ˜ธ์ถœ ๋ถ€๋ถ„ โ†’ log.error โ†’ console.error

๊ทธ ๊ฒฐ๊ณผ DevTools์—์„œ ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•˜๋ฉด ํ˜ธ์ถœ ์œ„์น˜๊ฐ€ ํ•ญ์ƒ log.ts๋กœ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. ๋””๋ฒ„๊น…์„ ์œ„ํ•ด ๋กœ๊ทธ๋ฅผ ์ฐ์—ˆ๋Š”๋ฐ, ์ •์ž‘ ์ค‘์š”ํ•œ 'ํ˜ธ์ถœ ์ถœ์ฒ˜'๋ฅผ ๋ฐ”๋กœ ํ™•์ธํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋ถˆํŽธํ•จ์ด ์ƒ๊น๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์ฑ… (bind)

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ bind๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋กœ๊ทธ ์œ ํ‹ธ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

// log. ts
const noop = () => {};
 
export const log = {
  error: IS_LOCAL ? console.error.bind(console, '%c[ERROR]', 'color: red; font-weight: bold') : noop,
  info: IS_LOCAL ? console.info.bind(console, '%c[INFO]', 'color: blue; font-weight: bold') : noop,
};

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Devtools์˜ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค์— log.ts๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์•„ log.error()๋ฅผ ํ˜ธ์ถœํ•œ ์‹ค์ œ ์œ„์น˜๊ฐ€ ๊ทธ๋Œ€๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ bind๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋กœ๊ทธ ์œ ํ‹ธ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค์— log.ts ํŒŒ์ผ์ด ์ถ”๊ฐ€๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ ๋กœ๊ทธ๋ฅผ ํ˜ธ์ถœํ•œ ์œ„์น˜๋ฅผ Devtools์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์™œ bind๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํƒ ํŠธ๋ ˆ์ด์Šค์— log.tsํŒŒ์ผ์ด ํฌํ•จ๋˜์ง€ ์•Š๋Š”๊ฑธ๊นŒ์š”? ์ด๋Š” ๋‹จ์ˆœํ•œ ๋ฌธ๋ฒ• ํŠธ๋ฆญ์ด ์•„๋‹ˆ๋ผ ECMAScript ์ŠคํŽ™ ์ˆ˜์ค€์—์„œ bind ๋™์ž‘์ด ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์™œ bind์™€ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ์Šคํƒ ํŠธ๋ ˆ์ด์Šค์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“ค๊นŒ์š”? ์ด๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด bind๊ฐ€ ๋งŒ๋“ค์–ด๋‚ด๋Š” ํŠน์ด ํ•จ์ˆ˜ ๊ฐ์ฒด(exotic function object)์— ๋Œ€ํ•ด ์•Œ์•„๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์™œ bind๋Š” ๋‹ค๋ฅผ๊นŒ?

MDN์˜ bind ๊ณต์‹ ๋ฌธ์„œ ๋ถ€๋ถ„์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์„ค๋ช…์ด ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

bind() ํ•จ์ˆ˜๋Š” ์ƒˆ๋กœ์šด ๋ฐ”์ธ๋”ฉํ•œ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ฐ”์ธ๋”ฉํ•œ ํ•จ์ˆ˜๋Š” ์›๋ณธ ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ๊ฐ์‹ธ๋Š” ํ•จ์ˆ˜๋กœ, ECMAScript 2015์—์„œ ๋งํ•˜๋Š” ํŠน์ด ํ•จ์ˆ˜ ๊ฐ์ฒด(exotic function object)์ž…๋‹ˆ๋‹ค. ๋ฐ”์ธ๋”ฉํ•œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ผ๋ฐ˜์ ์œผ๋กœ ๋ž˜ํ•‘๋œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ ๋ฉ๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ํŠน์ด ํ•จ์ˆ˜ ๊ฐ์ฒด๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”? ์ด๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋จผ์ € JavaScript์˜ ๊ฐ์ฒด๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ถ„๋ฅ˜๋˜๋Š”์ง€ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

JavaScript์˜ ๊ฐ์ฒด ๋ถ„๋ฅ˜

JavaScript์˜ ๊ฐ์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตฌ์กฐ๋กœ ๋ถ„๋ฅ˜๋ฉ๋‹ˆ๋‹ค. Javascript์˜ ๋Œ€๋ถ€๋ถ„์˜ ๋‚ด์žฅ ๊ฐ์ฒด๋“ค์€ ๊ธฐ๋ณธ Object๋ฅผ ์œ„์ž„๋ฐ›์•„ ๊ตฌํ˜„๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. prototype์„ ์ญ‰ ๋”ฐ๋ผ๊ฐ€๋ณด๋ฉด ์ข…์ฐฉ์ง€๊ฐ€ Object๊ฐ€ ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์€๋ฐ์š”. ์ด๋Ÿฐ ๊ฐ์ฒด๋“ค๋„ ๋ถ„๋ฅ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ๋งํ•˜๋Š” ๊ฐ์ฒด์™€, ๊ทธ ๊ฐ์ฒด๋ฅผ ์œ„์ž„๋ฐ›์•„ ๊ตฌํ˜„๋˜์—ˆ์ง€๋งŒ ํŠน์ด ๋™์ž‘์ด ์ถ”๊ฐ€๋œ ํŠน์ด ๊ฐ์ฒด๋“ค, ๊ทธ๋ฆฌ๊ณ  ๊ทธ ํŠน์ด ๊ฐ์ฒด์ค‘์—์„œ๋„ ํ•จ์ˆ˜๊ฐ์ฒด์™€, ํ•จ์ˆ˜์ค‘์—์„œ๋„ ํŠน์ด ๋™์ž‘์ด ์žˆ๋Š” ํŠน์ด ํ•จ์ˆ˜ ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”๋ฐ์š”. ๊ทธ๋Ÿผ ์ด ๋ถ„๋ฅ˜๋“ค์„ ์ฐจ๊ทผ์ฐจ๊ทผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Ordinary Object (์ผ๋ฐ˜ ๊ฐ์ฒด)

const obj = {
  a: 1,
  b: 2,
  c: 3,
};

๋จผ์ € ์ผ๋ฐ˜ ๊ฐ์ฒด๋Š” {} ๋˜๋Š” new Object()๋กœ ์ƒ์„ฑ๋˜๋Š” ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์•„๋Š” ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ECMAScript์˜ ๊ธฐ๋ณธ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ(ordinary behavior) ๋ฅผ ๊ทธ๋Œ€๋กœ ๋”ฐ๋ฅด๊ณ , ํ”„๋กœํผํ‹ฐ ์ถ”๊ฐ€ / ์ˆ˜์ • / ์‚ญ์ œ๊ฐ€ ์ง๊ด€์ ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ฝ˜์†”์ฐฝ์—์„œ ์ถœ๋ ฅํ–ˆ์„ ๋•Œ prototype ์ฒด์ธ ๋ฐ”๋กœ ์œ„์ชฝ์— Object๊ฐ€ ๋ฐ”๋กœ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ผ๋ฐ˜ ๊ฐ์ฒด๋ผ๊ณ  ๋ณด๋ฉด ๋˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Exotic Object (ํŠน์ด ๊ฐ์ฒด)

๊ทธ๋ ‡๋‹ค๋ฉด ํŠน์ด ๊ฐ์ฒด๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด๋ž‘ ๋ฌด์—‡์ด ๋‹ค๋ฅด๊ฒŒ "ํŠน์ด"์ผ๊นŒ์š”? ์‚ฌ์‹ค ๊ทธ๋ ‡๊ฒŒ ํŠน๋ณ„ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๊ณ  ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๋ชจ๋“  ๊ฒƒ์ด๋ผ๊ณ  ๋ณด๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€์ ์œผ๋กœ ์ผ๋ฐ˜์ ์ธ ๊ฐ์ฒด๋ณด๋‹ค ์ถ”๊ฐ€์ ์ธ ๋™์ž‘์ด ์žˆ๋Š” ๊ฒƒ์ด์ฃ . ๊ฒ‰๋ณด๊ธฐ์—๋Š” ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ (๊ฒ‰๋ณด๊ธฐ์— ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋ณด์ธ๋‹ค๋Š” ๊ฒƒ์€ typeof๋กœ ํ™•์ธํ–ˆ์„ ๋•Œ 'object'๋กœ ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค)ํ”„๋กœํผํ‹ฐ ์ ‘๊ทผ, ๊ธธ์ด ๋ณ€๊ฒฝ, ํ˜ธ์ถœ ๋ฐฉ์‹ ๋“ฑ ์ผ๋ฐ˜ ๊ฐ์ฒด์™€ ๋‹ค๋ฅธ ๊ทœ์น™์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ๋Š” Array, arguments, Function, Bound Function (bind๋กœ ์ƒ์„ฑ๋œ ํ•จ์ˆ˜) ๋“ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๊นŒ ์œ„์—์„œ ๋ดค๋˜ ๋‹ค์ด์–ด๊ทธ๋žจ ์ค‘์—์„œ ํ•จ์ˆ˜ ๊ฐ์ฒด, ํŠน์ด ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ๋”ฐ๋กœ ๋‹ค๋ฃฐ ํ…Œ๋‹ˆ ์šฐ์„  ํŠน์ด ๊ฐ์ฒด์— ์†ํ•˜๋Š” Array์— ๋Œ€ํ•ด์„œ ๋จผ์ € ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Array๋กœ ์•Œ์•„๋ณด๋Š” Exotic Object

Array๋Š” ๋„ˆ๋ฌด ์ผ์ƒ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋‹ค ๋ณด๋‹ˆ ๋”ฑํžˆ โ€œํŠน์ดํ•˜๋‹คโ€๊ณ  ๋А๊ปด์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ECMAScript ์ŠคํŽ™ ๊ด€์ ์—์„œ ๋ณด๋ฉด, Array๋Š” ๋งค์šฐ ํŠน์ดํ•œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿผ Array๋Š” ์™œ ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ํŠน์ด ๊ฐ์ฒด์ธ์ง€, ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

const arr = [];
 
arr[2] = 20;
 
console.log(arr.length); // 3
 
arr.length = 20;
console.log(arr); // (20) [empty ร— 2, 20, empty ร— 17]

arr.length๋ฅผ 20์œผ๋กœ ์„ค์ •ํ–ˆ์„ ๋ฟ์ธ๋ฐ, ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ์š”์†Œ์˜ ์ˆ˜๊ฐ€ ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค. ์™œ ๊ทธ๋Ÿด๊นŒ์š”? ๋ฐ”๋กœ ๋ฐฐ์—ด์˜ length๋Š” ๋‹จ์ˆœํ•œ ์ˆซ์ž ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ Array๊ฐ€ 'ํŠน์ด'ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋‹จ์ˆœํžˆ ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋˜์—ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

{
  2: 20,
  length: 20
}

์ฆ‰, ์ธ๋ฑ์Šค์™€ length ์‚ฌ์ด์— ์•„๋ฌด๋Ÿฐ ์—ฐ๊ด€๋„ ์—†๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋™์ž‘ํ–ˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ 'ํŠน์ด'ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ธ๋ฑ์Šค์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ฆ๊ฐ€ํ•˜๊ณ , length๋ฅผ ๋Š˜๋ ค๋„ ์‹ค์ œ ์š”์†Œ๊ฐ€ ์ฑ„์›Œ์ง€์ง€ ์•Š์€ ์ฑ„ empty๋กœ ๊ธธ์ด๋งŒ ๋Š˜์–ด๋‚˜๋Š” ๋™์ž‘์ด ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

์ด๋Š” Array๊ฐ€ ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๋ฐฐ์—ด ์ „์šฉ ์ŠคํŽ™์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅํ•œ ๋™์ž‘์ž…๋‹ˆ๋‹ค. ECMAScript์— ์ •์˜๋œ [[DefineOwnProperty]]์™€ ArraySetLength ๊ทœ์น™์„ ๊ธฐ์ค€์œผ๋กœ, ์œ„ ์ฝ”๋“œ๊ฐ€ ์™œ ์ด๋Ÿฐ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋Š”์ง€ ๊ฐ„๋‹จํžˆ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1. arr[2] = 20

  • "2"๋Š” ์œ ํšจํ•œ ๋ฐฐ์—ด ์ธ๋ฑ์Šค๋ผ์„œ 10.4.2.1์˜ 2๋ฒˆ ์ŠคํŽ™์„ ๋”ฐ๋ฅด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ์ด ์ŠคํŽ™์— ๋”ฐ๋ผ ๋ฐฐ์—ด์€ ์ธ๋ฑ์Šค๊ฐ€ length ์ด์ƒ์ด๋ฉด length = index + 1๋กœ ์ž๋™ ์ฆ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ arr.length === 3์ด ๋ฉ๋‹ˆ๋‹ค.

2. arr.length = 20

Array๋Š” length์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋ฉด 10.4.2.4์˜ 12๋ฒˆ ์ŠคํŽ™์— ๋”ฐ๋ผ์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ธธ์ด๊ฐ€ ๋Š˜์–ด๋‚˜๋ฉด
  • ์‹ค์ œ ์š”์†Œ๋ฅผ ์ฑ„์šฐ์ง€ ์•Š๊ณ 
  • ๋นˆ ์Šฌ๋กฏ(hole) ์„ ์ƒ์„ฑํ•œ๋‹ค

์ด์ฒ˜๋Ÿผ Array๋Š” ๊ฒ‰๋ณด๊ธฐ์—” ํ‰๋ฒ”ํ•˜์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๋ณ„๋„์˜ ๊ทœ์น™์„ ๋”ฐ๋ฅด๋Š” Exotic Object์ž…๋‹ˆ๋‹ค. ์ด์ œ ์ด ๊ฐœ๋…์„ ํ•จ์ˆ˜์— ๊ทธ๋Œ€๋กœ ์ ์šฉํ•ด๋ณด๋ฉด, ์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์“ฐ๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ bind๊ฐ€ ์™œ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ๋งŒ๋“œ๋Š”์ง€ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Function Exotic Object

์•„๊นŒ ์œ„ ๋‹ค์ด์–ด๊ทธ๋žจ์—์„œ ๋ณด์•˜๋“ฏ์ด ํŠน์ด ๊ฐ์ฒด ์•ˆ์—๋Š” Function ์ฆ‰ ํ•จ์ˆ˜ ๊ฐ์ฒด๋„ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด JavaScript์˜ ํ•จ์ˆ˜๋„ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ํ•˜์ง€๋งŒ ์—ฌ๊ธฐ์— [[Call]] ๊ทœ์น™์ด ์ถ”๊ฐ€๋œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ถ”๊ฐ€์ ์ธ ๋™์ž‘์ด ์ •์˜๋˜์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— "ํŠน์ด"๊ฐ์ฒด์ธ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ๋ชจ๋“  ๋™์ž‘์„ ์„ธ์„ธํžˆ ์‚ดํŽด๋ณด๊ธฐ ๋ณด๋‹ค๋Š” [[Call]]์˜ ์ŠคํŽ™์„ ์œ„์ฃผ๋กœ ๋ณด๋ฉฐ bind์™€ ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ๋Š”์ง€๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์‚ดํŽด๋ณผ๊ฑด๋ฐ์š”.

๊ทธ๋Ÿผ Function์˜ [[Call]]๋ช…์„ธ๋ฅผ ํ•œ๋ฒˆ ์‚ดํŽด๋ณผ๊นŒ์š”?

10.2.1-2๋ฒˆ ๋ช…์„ธ๋ฅผ ๋ณด๋ฉด PrepareForOrdinaryCall ๋‚ด๋ถ€ ๋กœ์ง์ด ์ƒˆ๋กœ์šด ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ด๋ฅผ ์ฝœ์Šคํƒ์˜ ๋งจ ์œ„์— Pushํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  10.2.1-3๋ฒˆ์—์„œ ๋ฐฉ๊ธˆ ์ƒ์„ฑ๋œ calleeContext๊ฐ€ ํ˜„ ์‹คํ–‰ ์ค‘์ธ ์ปจํ…์ŠคํŠธ๊ฐ€ ๋˜์—ˆ์Œ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๋ก ์ ์œผ๋กœ ์ •๋ฆฌํ•˜์ž๋ฉด, ์ผ๋ฐ˜ ํ•จ์ˆ˜์˜ Call์€ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์˜ ์ƒ์„ฑ์„ ๋™๋ฐ˜ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Bind Exotic Object

์ด์ œ ํŠน์ด ํ•จ์ˆ˜ ๊ฐ์ฒด์ธ bind๋ฅผ ์‚ดํŽด๋ณผ ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค.
์ง€๊ธˆ๊นŒ์ง€ Object, Array, Function์„ ์ˆœ์„œ๋Œ€๋กœ ์‚ดํŽด๋ณธ ์ด์œ ๋„ ๊ฒฐ๊ตญ ์ด bind์˜ ๋™์ž‘์„ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•จ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด bind๋Š” ์ผ๋ฐ˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ๋ฌด์—‡์ด ๋‹ค๋ฅผ๊นŒ์š”?
console.log ์œ ํ‹ธ์—์„œ ํ•ต์‹ฌ์ด ๋˜๋Š” ์ง€์ ์€ bind์˜ [[Call]] ๋™์ž‘์ด๊ธฐ ๋•Œ๋ฌธ์—, ์—ฌ๊ธฐ์„œ๋„ Function๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ [[Call]] ๋™์ž‘์— ์ดˆ์ ์„ ๋งž์ถฐ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Theย [[Call]]ย internal method of aย bound function exotic objectย Fย takes argumentsย thisArgumentย (anย ECMAScript language value) andย argumentsListย (aย Listย ofย ECMAScript language values) and returns either aย normal completion containingย anย ECMAScript language valueย or aย throw completion. It performs the following steps when called:

  1. Letย targetย beย F.[[BoundTargetFunction]].
  2. Letย boundThisย beย F.[[BoundThis]].
  3. Letย boundArgsย beย F.[[BoundArguments]].
  4. Letย argsย be theย list-concatenationย ofย boundArgsย andย argumentsList.
  5. Return ?ย Call(target,ย boundThis,ย args).

bind์˜ [[Call]]์€ 10.2.1์˜ ํ•จ์ˆ˜ [[Call]]๊ณผ๋Š” ๋‹ค๋ฅธ ๋™์ž‘์„ ๋ณด์ž…๋‹ˆ๋‹ค. ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ถ„์€ ์—†๊ณ , ๊ธฐ์กด์— ์ €์žฅํ•ด๋‘” ์ •๋ณด๋ฅผ ๊บผ๋‚ด์–ด ์žฌ์กฐํ•ฉํ•˜๋Š” ๊ณผ์ •์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์™€ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

function add(a, b) {
  return a + b;
}
 
const add10 = add.bind(null, 10);

bind๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ECMAScript ์ŠคํŽ™ 20.2.3.2์˜ 3๋ฒˆ ๊ทœ์น™์— ๋”ฐ๋ผ์„œ BoundFunctionCreate๊ฐ€ ์‹คํ–‰๋˜๊ณ , Bound Function Exotic Object๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด์„œ ์•„๋ž˜์™€ ๊ฐ™์€ ์ •๋ณด๋“ค์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

add10.`[[BoundTargetFunction]]` === add
add10.`[[BoundThis]]` === null
add10.`[[BoundArguments]]` === [10]

๊ทธ๋ž˜์„œ Call์ด ์‹คํ–‰๋˜๋ฉด ์ด ์ €์žฅ๋œ ์ •๋ณด๋“ค์„ ํ™œ์šฉํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  Call์„ ๋ฐ˜ํ™˜ํ•ด์„œ ์ œ์–ด๊ถŒ์„ ๋„˜๊น๋‹ˆ๋‹ค.

function vs bind

๊ทธ๋Ÿผ ์ŠคํŽ™์ƒ์œผ๋กœ ์‚ดํŽด๋ดค๋˜ functiond์ด๋ž‘ bind์˜ ์‹ค์ œ ๋™์ž‘ ์ฐจ์ด๋ฅผ ์ง์ ‘ ๋ณผ๊นŒ์š”? ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์—์„œ ์‹คํ–‰ํ•˜๊ณ , debugger๊ฐ€ ๋ฉˆ์ถ˜ ์‹œ์ ์— callstack์— ์–ด๋–ค ๋ณ€ํ™”๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ง์ ‘ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

const person = {
  name: 'Gemini',
  greet: function(message) {
    debugger; 
    console.log(`${message}, ${this.name}!`);
  }
};
 
// 1. ์ผ๋ฐ˜ ํ•จ์ˆ˜ ํ˜ธ์ถœ (10.2.1 `[[Call]]`)
console.log('%c--- ์ผ๋ฐ˜ ํ˜ธ์ถœ ์‹œ์ž‘ ---', 'color: blue; font-weight: bold');
person.greet('Hello');
 
// 2. ๋ฐ”์ธ๋“œ ํ•จ์ˆ˜ ์ƒ์„ฑ ๋ฐ ํ˜ธ์ถœ (10.4.1.1 `[[Call]]`)
const boundGreet = person.greet.bind(person, 'Hi');
debugger
 
console.log('%c--- ๋ฐ”์ธ๋“œ ํ˜ธ์ถœ ์‹œ์ž‘ ---', 'color: green; font-weight: bold');
boundGreet();

๋จผ์ € 1๋ฒˆ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ์‹œ์ ์— greet ๋‚ด๋ถ€์—์„œ debugger๋ฅผ ํ†ตํ•ด ๋ฉˆ์ถฐ๋ณด๋ฉด, callstack์— greet ํ•จ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  2๋ฒˆ boundGreet ๋‹ค์Œ์ค„์—์„œ debugger๋ฅผ ์‹คํ–‰ํ•ด๋ณด๋ฉด bind์—ฐ์‚ฐ์€ ๋‹จ์ˆœํžˆ boundGreet์— bind target๊ฐ™์€ ์ •๋ณด๋ฅผ ์ €์žฅํ•œ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ์ฝœ์Šคํƒ์— ์ถ”๊ฐ€๋˜๋Š” ๊ฐ’์ด ์—†๊ณ , greet ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ฐํžŒ debugger๋ฅผ ๋ณด๋ฉด callstack์— greet๋งŒ ์กด์žฌํ•˜๊ณ , ๋ณ„๋„์˜ boundGreet๋Š” ์—†๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด bind์˜ call์€ ์ž๊ธฐ ์ž์‹ ์— ๋Œ€ํ•œ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , target function์˜ Call๋กœ ์œ„์ž„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ . ๋”ฐ๋ผ์„œ target function์„ ๊ธฐ์ค€์œผ๋กœ ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด์ฒ˜๋Ÿผ bind๋Š” ์‹ค์ œ๋กœ ์ฝœ์Šคํƒ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์‹œ log.ts๋กœ ๋Œ์•„์™€์„œ

๊ทธ๋Ÿผ ์œ„ ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ์™œ bind๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํƒ ํŠธ๋ ˆ์ด์Šค ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋Š”์ง€ ์ •๋ฆฌํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • bind๋Š” ์ผ๋ฐ˜์ ์ธ JavaScript ๋ž˜ํผ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  Bound Function Exotic Object๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ๊ฐ์ฒด๋Š” ํ˜ธ์ถœ ์‹œ ์ƒˆ๋กœ์šด JavaScript ์ฝ”๋“œ ๋ ˆ๋ฒจ์˜ ์ƒˆ๋กœ์šด ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๋‚ด๋ถ€ [[Call]] ์ถ”์ƒ ์—ฐ์‚ฐ์„ ํ†ตํ•ด ๊ณง๋ฐ”๋กœ ๋Œ€์ƒ ํ•จ์ˆ˜(console.error ๋“ฑ)๋กœ ํ˜ธ์ถœ์„ ์œ„์ž„ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ๊ฒฐ๊ณผ DevTools์˜ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค์—๋Š” log.ts์™€ ๊ฐ™์€ ์œ ํ‹ธ ๋ ˆ์ด์–ด๊ฐ€ ๋ผ์–ด๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋Œ€๋กœ error: () => console.error(...) ์ฒ˜๋Ÿผ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋‚˜ ์ผ๋ฐ˜ ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ๋ฉด, ํ•ด๋‹น ํ•จ์ˆ˜ ์ž์ฒด๊ฐ€ JS ์‹คํ–‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋ฏ€๋กœ log.ts๊ฐ€ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค์— ๋‚จ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ธŒ๋ผ์šฐ์ €์˜ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋Š” JavaScript ์‹คํ–‰ ์ปจํ…์ŠคํŠธ(ํ•จ์ˆ˜ ํ˜ธ์ถœ ํ”„๋ ˆ์ž„) ๋‹จ์œ„๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ, ECMAScript ์ŠคํŽ™์˜ ์ถ”์ƒ ์—ฐ์‚ฐ([[Call]] ๋“ฑ) ์ž์ฒด๋Š” JS ์‹คํ–‰ ํ”„๋ ˆ์ž„์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ถ”์  ๋Œ€์ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋งˆ๋ฌด๋ฆฌ

๋งŒ์•ฝ bind์˜ ๋‚ด๋ถ€ ๋™์ž‘์„ ์•Œ์ง€ ๋ชปํ–ˆ๋‹ค๋ฉด ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋ฅผ ์ถ”์ ํ•ด์„œ ๋‘๋ฒˆ์งธ ์Šคํƒ ํŠธ๋ ˆ์ด์Šค๋กœ ๊ฒฝ๋กœ๋ฅผ ๋”ฐ๋กœ ๋„์šฐ๋Š” ๋“ฑ์˜ ํ•ด๊ฒฐ์ฑ…์„ ์‚ฌ์šฉํ–ˆ์„ ๊ฒƒ ๊ฐ™์€๋ฐ, ECMAScript ์ŠคํŽ™์„ ๊ธฐ์ค€์œผ๋กœ ๋™์ž‘์„ ์ดํ•ดํ•˜๊ณ  ๋‚˜๋‹ˆ ๋ถˆํ•„์š”ํ•œ ๋ณต์žกํ•จ ์—†์ด ๊ฐ€์žฅ ๊น”๋”ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•ด ๋ณด์ด๋Š” ์œ ํ‹ธ์ด๋ผ๋„ ๋‚ด๋ถ€ ๋™์ž‘์„ ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๋ฉด ๋” ๋‚˜์€ ์„ค๊ณ„๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋А๋ผ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ  ๋ฌธ์„œ

console.log ์œ ํ‹ธ์„ ๋งŒ๋“ค๋‹ค๊ฐ€ bind ํ•จ์ˆ˜์˜ ๋™์ž‘ ๋ฐฉ์‹ ํŒŒํ—ค์ณ๋ณด๊ธฐ