πŸ“’ ν•¨μˆ˜μ™€ 일급객체

zooyahoΒ·2022λ…„ 7μ›” 25일
0
post-thumbnail

ν•¨μˆ˜μ™€ 일급객체

ν•¨μˆ˜λ₯Ό 객체와 λ™μΌν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€λŠ” 의미이며 λŸ°νƒ€μž„μ— ν•¨μˆ˜ 객체둜 ν‰κ°€λœλ‹€.

✍️ 쑰건

  • 무λͺ…μ˜ λ¦¬ν„°λŸ΄λ‘œ 생성할 수 μžˆλ‹€. 즉, λŸ°νƒ€μž„μ— 생성이 κ°€λŠ₯ν•˜λ‹€.
  • λ³€μˆ˜λ‚˜ 자료ꡬ쑰(객체, λ°°μ—΄)에 μ €μž₯ν•  수 μžˆλ‹€.
  • ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜μ— 전달할 수 μžˆλ‹€.
  • ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.

● ν•¨μˆ˜ 객체의 ν”„λ‘œνΌν‹°

  • ν•¨μˆ˜ κ°μ²΄λŠ” μΌλ°˜κ°μ²΄μ—λŠ” μ—†λŠ” ν•¨μˆ˜ 고유의 ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ ν•œλ‹€.
  • Object.getOwnPropertyDescriptors()λ©”μ„œλ“œλ‘œ ν•¨μˆ˜μ˜ λͺ¨λ“  ν”„λ‘œνΌν‹°μ˜ ν”„λ‘œνΌν‹° μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό 확인할 수 μžˆλ‹€.
  • 상속 받은 __proto__λŠ” Object.getOwnPropertyDescriptors()λ©”μ„œλ“œλ‘œ ν™•μΈν•˜λ©΄ undefinedκ°€ λ°˜ν™˜λœλ‹€.!!
function square(num) {
  return num * num;
}

console.log(Object.getOwnPropertyDescriptors(square));

1. arguments ν”„λ‘œνΌν‹°

  • arguments ν”„λ‘œνΌν‹°μ˜ 값은 arguments 객체닀.
  • ν•¨μˆ˜ 호좜 μ‹œ μ „λ‹¬λœ μΈμˆ˜λ“€μ˜ 정보λ₯Ό λ‹΄κ³  μžˆλŠ” 순회 κ°€λŠ₯ν•œ μœ μ‚¬ λ°°μ—΄ 객체이닀.
  • ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 지역 λ³€μˆ˜μ²˜λŸΌ μ‚¬μš©λœλ‹€.
  • 초과된 μΈμˆ˜λŠ” μ•”λ¬΅μ μœΌλ‘œ arguments객체의 ν”„λ‘œνΌν‹°λ‘œ λ³΄κ΄€λœλ‹€.
  • argumentsκ°μ²΄λŠ” λ§€κ°œλ³€μˆ˜μ˜ 개수λ₯Ό ν™•μ •ν•  수 μ—†λŠ” κ°€λ³€ 인자 ν•¨μˆ˜λ₯Ό μˆ˜ν˜„ν•  λ•Œ μœ μš©ν•˜λ‹€.

πŸ“Ž callee ν”„λ‘œνΌν‹°

  • arguments객체의 callee ν”„λ‘œνΌν‹°λŠ” ν•¨μˆ˜ μžμ‹ μ„ 가리킨닀.

πŸ“Ž length ν”„λ‘œνΌν‹°

  • arguments객체의 length ν”„λ‘œνΌν‹°λŠ” 인수의 개수λ₯Ό 가리킨닀.

πŸ“Ž Symbol(Symbol.iterator) ν”„λ‘œνΌν‹°

  • arguments객체λ₯Ό 순회 κ°€λŠ₯ν•œ 자료ꡬ쑰인 μ΄ν„°λŸ¬λΈ”λ‘œ λ§Œλ“€κΈ° μœ„ν•œ ν”„λ‘œνΌν‹°μ΄λ‹€. Symbol.iteratorλ₯Ό ν”„λ‘œνΌν‹° ν‚€λ‘œ μ‚¬μš©ν•œ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜λŠ” 것에 μ˜ν•΄ μ΄ν„°λŸ¬λΈ”μ΄ λœλ‹€.

✍️ arguments객체에 λ°°μ—΄ λ©”μ„œλ“œ μ‚¬μš©

  • μœ μ‚¬ λ°°μ—΄ κ°μ²΄λŠ” 배열이 μ•„λ‹ˆλ―€λ‘œ λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  수 μ—†μ§€λ§Œ Function.prototype.call, Function.prototype.applyλ₯Ό μ‚¬μš©ν•΄ κ°„μ ‘ 호좜 ν›„ μ‚¬μš©ν•  수 μžˆλ‹€.

πŸ‘Ύ#01

function sum() {
  const array = Array.prototype.slice.call(arguments);
  return array.reduce(function (pre, cur) {
    return pre + cur;
  }, 0);
}

console.log(sum(1, 3)); // 4

πŸ‘Ύ#02 - RestνŒŒλΌλ―Έν„° μ‚¬μš©

function sum(...args) {
  return args.reduce((pre, cur) => pre + cur, 0);
}

console.log(sum(1, 3, 4)); // 8

2. length ν”„λ‘œνΌν‹°

  • arguments 객체의 lenthν”„λ‘œνΌν‹°λŠ” 인자의 개수λ₯Ό 가리킀고, ν•¨μˆ˜ 객체의 lengthν”„λ‘œνΌν‹°λŠ” λ§€κ°œλ³€μˆ˜μ˜ 개수λ₯Ό 가리킨닀!!!
function bar(x) {
  console.log(bar.length); // 1
  console.log(arguments.length); // 3
  return x;
}
bar(1, 2, 3);

3. name ν”„λ‘œνΌν‹°

  • ν•¨μˆ˜ 이름을 λ‚˜νƒ€λ‚Έλ‹€.
const namedFn = function foo() {};
console.log(namedFn.name); // foo

const anonymousFn = function () {};
console.log(anonymousFn.name); // anonymousFn

function bar() {}
console.log(bar.name); // bar

🚨 참고

πŸ”₯ ν•¨μˆ˜λ₯Ό 일반 ν•¨μˆ˜λ‘œμ„œ ν˜ΈμΆœν•˜λ©΄ ν•¨μˆ˜ 객체의 λ‚΄λΆ€ λ©”μ„œλ“œ[[Call]]이 ν˜ΈμΆœλœλ‹€.  
πŸ”₯ new μ—°μ‚°μžλ‘œ ν˜ΈμΆœν•œ μƒμ„±μž ν•¨μˆ˜λŠ” λ‚΄λΆ€ λ©”μ„œλ“œμΈ[[Construct]]λ₯Ό ν˜ΈμΆœν•œλ‹€.  
πŸ”₯ [[Construct]]λ₯Ό 가지고 μžˆλŠ” ν•¨μˆ˜ 객체λ₯Ό constructor둜, [[Construct]]λ₯Ό 가지고 μžˆλŠ” μ•ŠλŠ” ν•¨μˆ˜ 객체λ₯Ό non-constructor둜 κ΅¬λΆ„ν•œλ‹€.  
πŸ”₯ μΌλ°˜ν•¨μˆ˜(function(){}), ν•¨μˆ˜ μ„ μ–Έλ¬Έ, ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜λ§Œμ΄ `constructor`이고 ν™”μ‚΄ν‘œ ν•¨μˆ˜μ™€ λ©”μ„œλ“œ μΆ•μ•½ν‘œν˜„μœΌλ‘œ μ •μ˜λœ ν•¨μˆ˜λŠ” `non-constructor`이닀.

4. prototype ν”„λ‘œνΌν‹°

  • prototype ν”„λ‘œνΌν‹°μ€ μƒμ„±μž ν•¨μˆ˜λ‘œ ν˜ΈμΆœν•  수 μžˆλŠ” ν•¨μˆ˜ 객체. 즉 constructor만이 μ†Œμœ ν•  수 μžˆλŠ” ν”„λ‘œνΌν‹°μ΄λ‹€.
  • μƒμ„±μž ν•¨μˆ˜κ°€ 생성할 μΈμŠ€ν„΄μŠ€μ˜ ν”„λ‘œν† νƒ€μž… 객체λ₯Ό 가리킨닀.
// ν•¨μˆ˜ κ°μ²΄λŠ” prototype ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ ν•œλ‹€.
(function () {}.hasOwnProperty("prototype")); // true

// 일반 κ°μ²΄λŠ” prototype ν”„λ‘œνΌν‹°κ°€ μ—†λ‹€.
({}.hasOwnProperty("prototype")); // false

πŸ‘‰πŸ» hasOwnProperty()λ©”μ„œλ“œλŠ” 인수둜 전달받은 ν”„λ‘œνΌν‹° ν‚€κ°€ 객체 고유의 ν”„λ‘œνΌν‹° 킀인 κ²½μš°μ—λ§Œ trueλ₯Ό λ°˜ν™˜ν•˜κ³  상속받은 ν”„λ‘œν† νƒ€μž…μ˜ ν”„λ‘œνΌν‹°μΈ 경우 falseλ₯Ό λ°˜ν™˜ν•œλ‹€.

5. __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°

  • __proto__λŠ” Object.prototype 객체의 μ ‘κ·Όμž ν”„λ‘œνΌν‹°μ΄λ‹€.(getter/setter ν•¨μˆ˜)
  • [[prototype]] λ‚΄λΆ€ μŠ¬λ‘―μ— 직접 μ ‘κ·Όν•  수 μ—†μœΌλ©°, __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό 톡해 κ°„μ ‘μ μœΌλ‘œ ν”„λ‘œν† νƒ€μž… 객체에 μ ‘κ·Όν•  수 μžˆλ‹€.

πŸ‘‰πŸ» __proto__λŠ” square ν•¨μˆ˜μ˜ ν”„λ‘œνΌν‹°κ°€ μ•„λ‹Œ, Object.prototype 객체의 ν”„λ‘œνΌν‹°λ₯Ό 상속받은 ν”„λ‘œνΌν‹°μ΄λ‹€.
πŸ‘‰πŸ» Object.prototype 객체의 __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λŠ” λͺ¨λ“  객체가 μ‚¬μš©ν•  수 μžˆλ‹€.

🚨 [[prototype]] λ‚΄λΆ€ 슬둯과 __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°

πŸ‘‰πŸ» [[prototype]] λ‚΄λΆ€ μŠ¬λ‘―μ€ 직접 μ ‘κ·Όν•  수 μ—†μœΌλ―€λ‘œ 
Object.prototype 객체의 __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•˜μ—¬ μ ‘κ·Όν•΄μ•Ό ν•œλ‹€. πŸ‘‰πŸ» newν‚€μ›Œλ“œλ‘œ ν˜ΈμΆœν•œ μƒμ„±μž ν•¨μˆ˜λ§Œμ΄ [[prototype]] λ‚΄λΆ€ μŠ¬λ‘―μ„ κ°–λŠ”λ‹€. πŸ‘‰πŸ» __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λŠ” Object.prototype 객체의 ν”„λ‘œνΌν‹°λ‹€. πŸ‘‰πŸ» λͺ¨λ“  κ°μ²΄λŠ” Object.prototype 객체λ₯Ό 상속받아 __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μ‚¬μš©ν•  수 μžˆμ§€λ§Œ,
일반 κ°μ²΄λŠ” [[prototype]] λ‚΄λΆ€ μŠ¬λ‘―μ„ 가지고 μžˆμ§€ μ•Šμ•„ __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°κ°€ ν•„μš” μ—†λ‹€!
ν•˜μ§€λ§Œ [[prototype]] λ‚΄λΆ€ μŠ¬λ‘―μ„ 가지고 μžˆλŠ” μƒμ„±μž ν•¨μˆ˜(ν•¨μˆ˜ 객체)λŠ” __proto__λ₯Ό μ‚¬μš©ν•˜μ—¬
[[prototype]] λ‚΄λΆ€ μŠ¬λ‘―μ— κ°„μ ‘ μ ‘κ·Όν•œλ‹€.

μ°Έκ³  λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive

profile
즐겁게 κ°œλ°œν•˜μž μ₯¬μ•Όν˜ΈπŸ‘»

0개의 λŒ“κΈ€