Skip to content

Latest commit

Β 

History

History

15-Function & First Class Object

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Β 
Β 

일급 객체

λ‹€μŒ 쑰건을 λ§Œμ‘±ν•˜λŠ” κ°μ²΄λŠ” 일급 객체 라고 ν•œλ‹€.

  • 무λͺ…μ˜ λ¦¬ν„°λŸ΄λ‘œ 생성할 수 μžˆλ‹€. 즉, λŸ°νƒ€μž„μ— 생성이 κ°€λŠ₯ν•˜λ‹€.
  • λ³€μˆ˜λ‚˜ 자료ꡬ쑰(객체, λ°°μ—΄ λ“±)에 μ €μž₯ν•  수 μžˆλ‹€.
  • ν•¨μˆ˜μ˜ λ§€κ°λ³€μˆ˜μ— 전달할 수 μžˆλ‹€.
  • ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
// ν•¨μˆ˜λŠ” 무λͺ… λ¦¬ν„°λŸ΄λ‘œ 생성가λŠ₯
// ν•¨μˆ˜λŠ” λ³€μˆ˜μ— μ €μž₯ κ°€λŠ₯
// λŸ°νƒ€μž„ μ‹œμ μ— ν•¨μˆ˜ λ¦¬ν„°λŸ΄μ΄ ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체가 μƒμ„±λ˜κ³  λ³€μˆ˜μ— ν• λ‹Ή λœλ‹€.(μ •ν™•νžˆλŠ” ν•¨μˆ˜ 객체의 참쑰값이 ν• λ‹Ή λœλ‹€.)
const increase = function (num) {
  return ++num;
};

const decrease = function (num) {
  return --num;
};

// ν•¨μˆ˜λŠ” 객체에 μ €μž₯ν•  수 μžˆλ‹€.
const predicate = { increase, decrease };

// ν•¨μˆ˜λŠ” λ§€κ°œλ³€μˆ˜(= νŒŒλΌλ―Έν„°, parameter)에 전달할 수 μžˆλ‹€.
// ν•¨μˆ˜λŠ” ν•¨μˆ˜μ˜ λ°˜ν™˜ κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
function makeCounter(predicate) {
  let num = 0;

  return function () {
    num = predicate(num);
    return num;
  };
}

// ν•¨μˆ˜λŠ” 인수둜 ν•¨μˆ˜λ₯Ό 전달할 수 μžˆλ‹€.
const increaser = makeCounter(predicate.increase);
console.log(increaser()); // 1
console.log(increaser()); // 2

const decreaser = makeCounter(predicate.decrease);
console.log(decreaser()); // -1
console.log(decreaser()); // -2

일급 객체둜써 ν•¨μˆ˜κ°€ κ°€μ§€λŠ” κ°€μž₯ 큰 νŠΉμ§•

  • 일반 객체와 같이 ν•¨μˆ˜λ₯Ό ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜μ— 전달할 수 μžˆλ‹€.
  • ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.
  • λ‹€μŒ 2가지가 μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ ν•¨μˆ˜ν˜• ν”„λ‘œκ·Έλž˜λ°μ„ κ°€λŠ₯μΌ€ν•˜λŠ” μž₯점 쀑 ν•˜λ‚˜
  • μΆ”κ°€μ μœΌλ‘œ, 일반 κ°μ²΄λŠ” ν˜ΈμΆœν•  수 μ—†μ§€λ§Œ ν•¨μˆ˜ κ°μ²΄λŠ” 호좜이 κ°€λŠ₯ν•˜λ©°, ν•¨μˆ˜ κ°μ²΄λŠ” 고유의 ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ ν•œλ‹€.


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

ν•¨μˆ˜λ„ 객체(object)λ‹€. λ”°λΌμ„œ ν•¨μˆ˜λ„ ν”„λ‘œνΌν‹°λ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.


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

arguments 객체 λŠ” ν•¨μˆ˜ 호좜 μ‹œ μ „λ‹¬λœ 인수(argument)λ“€μ˜ 정보λ₯Ό λ‹΄κ³  μžˆλŠ” 순회 κ°€λŠ₯ν•œ(iterable) μœ μ‚¬ λ°°μ—΄ 객체이닀.

  • ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 지역 λ³€μˆ˜μ²˜λŸΌ μ‚¬μš©ν•  수 μžˆλŠ” arguments 객체λ₯Ό μ°Έμ‘°
  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜(parameter)와 인수(argument)의 κ°œμˆ˜κ°€ μΌμΉ˜ν•˜λŠ”μ§€ ν™•μΈν•˜μ§€ μ•ŠλŠ”λ‹€.
    • λ”°λΌμ„œ, ν•¨μˆ˜ 호좜 μ‹œ λ§€κ°œλ³€μˆ˜ 수만큼 인수λ₯Ό μ „λ‹¬ν•˜μ§€ μ•Šμ•„λ„ μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.
    • μ΄λŠ”, ν•¨μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ μ„ μ–Έν•œ λ§€κ°œλ³€μˆ˜λŠ” ν•¨μˆ˜κ°€ 호좜되면 ν•¨μˆ˜ λͺΈμ²΄ λ‚΄μ—μ„œ μ•”λ¬΅μ μœΌλ‘œ μ„ μ–Έλ˜κ³  undefined 둜 μ΄ˆκΈ°ν™”λœ ν›„, μΈμˆ˜κ°€ ν• λ‹Ήλ˜κΈ° λ•Œλ¬Έ
  • λ§€κ°œλ³€μˆ˜λ³΄λ‹€ 인수(argument)λ₯Ό 많이 μ „λ‹¬ν–ˆμ„ 경우, 초과된 μΈμˆ˜λŠ” λ¬΄μ‹œλ˜μ§€ μ•Šκ³ , arguments 객체의 ν”„λ‘œνΌν‹°μ— 보관
    • arguments κ°μ²΄λŠ” 기본적으둜 length ν”„λ‘œνΌν‹°λ₯Ό μ§€μ›ν•œλ‹€.
    • μ—¬κΈ°μ„œ lengthλŠ” 인수(argument)의 κ°œμˆ˜μ΄λ‹€.
    • length ν”„λ‘œνΌν‹° λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” μ΄μœ λŠ” arguments 객체 κ°€ μœ μ‚¬ λ°°μ—΄ 객체(array-like object) 이기 λ•Œλ¬Έμ΄λ‹€.
      • μœ μ‚¬ λ°°μ—΄ κ°μ²΄λž€ length ν”„λ‘œνΌν‹° λ₯Ό κ°€μ§€λŠ” 객체둜, for λ¬Έ 같은 반볡문으둜 μˆœνšŒκ°€λŠ₯ν•˜λ‹€.
  • arguments 객체 λŠ” λ§€κ°œλ³€μˆ˜ 개수λ₯Ό ν™•μ •ν•  수 μ—†λŠ” κ°€λ³€ 인자 ν•¨μˆ˜ λ₯Ό κ΅¬ν˜„ν•  λ•Œ μœ μš©ν•˜λ‹€.
function multiply(x, y) {
  console.log(arguments);
  console.log(`length : ${arguments.length}`);
  return x + y;
}

console.log(multiply());
/*
[Arguments] {}
length : 0
NaN
*/

console.log(multiply(1));
/*
[Arguments] { '0': 1 }
length : 1
NaN
*/

console.log(multiply(1, 2));
/*
[Arguments] { '0': 1, '1': 2 }
length : 2
3
*/

console.log(multiply(1, 2, 3, 4, 5));
/*
[Arguments] { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5 }
length : 5
3 
*/
  • arguments 객체 λŠ” μœ μ‚¬ λ°°μ—΄ 객체이지, λ°°μ—΄ κ·Έ μžμ²΄λŠ” μ•„λ‹ˆλ‹€.
    • λ”°λΌμ„œ, λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•  경우 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.
    • 이것을 보완할 λ°©λ²•μœΌλ‘œ ES6 λΆ€ν„° Rest νŒŒλΌλ―Έν„° κ°€ λ„μž…λ˜μ—ˆλ‹€.
    • Rest νŒŒλΌλ―Έν„°λ₯Ό 톡해 λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ μš©ν•  수 μžˆλ‹€.
// ES6 Rest Parameter
// argument 객체λ₯Ό μ‹€μ œ "λ°°μ—΄"처럼 μ‚¬μš©ν•  수 μžˆλ‹€.
function sum(...args) {
  console.log(args, Array.isArray(args));
  return args.reduce((acc, cur) => acc + cur, 0);
}

console.log(sum());
/*
[] true
0
*/

console.log(sum(1, 2));
/*
[ 1, 2 ] true
3
*/

console.log(sum(1, 2, 3, 4, 5));
/*
[ 1, 2, 3, 4, 5 ] true
15
*/

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

ν•¨μˆ˜ 객체의 length ν”„λ‘œνΌν‹° λŠ” ν•¨μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ μ„ μ–Έν•œ λ§€κ°œλ³€μˆ˜μ˜ 개수 λ₯Ό 가리킨닀.

  • μ£Όμ˜ν•  점은 arguments 객체 의 length ν”„λ‘œνΌν‹° β‰  ν•¨μˆ˜ 객체의 length ν”„λ‘œνΌν‹°
    • argument 객체의 length ν”„λ‘œνΌν‹° = 인수(argument)의 개수
    • ν•¨μˆ˜ 객체의 length ν”„λ‘œνΌν‹° = λ§€κ°œλ³€μˆ˜(parameter)의 개수
function add(x, y) {
  console.log(`add ν•¨μˆ˜ 객체의 length : ${add.length}, arguments 객체의 length : ${arguments.length}`);
  return x + y;
}

console.log(add());
/*
add ν•¨μˆ˜ 객체의 length : 2, arguments 객체의 length : 0
NaN
*/
console.log(add(1, 2));
/*
add ν•¨μˆ˜ 객체의 length : 2, arguments 객체의 length : 2
3
*/
console.log(add(1, 2, 3, 4, 5));
/*
add ν•¨μˆ˜ 객체의 length : 2, arguments 객체의 length : 5
3
*/

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

ν•¨μˆ˜ 객체의 name ν”„λ‘œνΌν‹° λŠ” ν•¨μˆ˜ 이름 을 λ‚˜νƒ€λ‚Έλ‹€.

  • 읡λͺ… ν•¨μˆ˜μ˜ 경우
    • ES5 μ—μ„œλŠ” β†’ 빈 λ¬Έμžμ—΄('')
    • ES6 μ—μ„œλŠ” β†’ ν•¨μˆ˜ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” μ‹λ³„μž λ₯Ό λ‚˜νƒ€λ‚Έλ‹€.
// ν•¨μˆ˜ 객체 name ν”„λ‘œνΌν‹° - κΈ°λͺ… ν•¨μˆ˜ ν‘œν˜„μ‹
const namedFunc = function foo() {};
console.log(namedFunc.name); // foo

// ν•¨μˆ˜ 객체 name ν”„λ‘œνΌν‹° - 무λͺ… ν•¨μˆ˜ ν‘œν˜„μ‹ πŸ”
// - ES5 μ—μ„œλŠ” 빈 λ¬Έμžμ—΄('')
// - ES6 μ—μ„œλŠ” ν•¨μˆ˜ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” μ‹λ³„μž
const anonymousFunc = function () {};
console.log(anonymousFunc.name); // anonymousFunc

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

proto μ ‘κ·Όμž ν”„λ‘œνΌν‹°

  • λͺ¨λ“  κ°μ²΄λŠ” [[ Prototype ]] μ΄λΌλŠ” λ‚΄λΆ€ μŠ¬λ‘―μ„ κ°–λŠ”λ‹€.
  • [[ Prototype ]] λ‚΄λΆ€ μŠ¬λ‘―μ€ Prototype 객체λ₯Ό 가리킨닀.

__proto__ ν”„λ‘œνΌν‹°λŠ” [[ Prototype ]] λ‚΄λΆ€ 슬둯이 κ°€λ¦¬ν‚€λŠ” ν”„λ‘œν† νƒ€μž… 객체에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” μ ‘κ·Όμž ν”„λ‘œνΌν‹°

  • 즉, 이 ν”„λ‘œνΌν‹°μ— 직접 μ ‘κ·Όν•  μˆ˜λŠ” μ—†κ³ , 간접적인 λ°©λ²•μœΌλ‘œ ν”„λ‘œν† νƒ€μž…μ— μ ‘κ·Όν•  수 μžˆλ‹€.
const obj = { a: 1 };

console.log(obj.__proto__ === Object.prototype); // true  (객체 λ¦¬ν„°λŸ΄ ν˜•νƒœλ‘œ μƒμ„±ν•œ 객체의 ν”„λ‘œν† νƒ€μž… κ°μ²΄λŠ” Object.prototype)

console.log(obj.hasOwnProperty("a")); // true  (obj κ°μ²΄μ—λŠ” a ν”„λ‘œνΌν‹°κ°€ μžˆμœΌλ‹ˆκΉ true)
console.log(obj.hasOwnProperty("__proto__")); // false (__proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λŠ” 직접 μ ‘κ·Όν•  수 μžˆλŠ” ν”„λ‘œνΌν‹°κ°€ μ•„λ‹ˆλ―€λ‘œ false)

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

prototype ν”„λ‘œνΌν‹°λŠ” μƒμ„±μž ν•¨μˆ˜λ‘œ ν˜ΈμΆœν•  수 μžˆλŠ” ν•¨μˆ˜ 객체 , 즉 constructor 만이 μ†Œμœ ν•˜λŠ” ν”„λ‘œνΌν‹°

  • 일반 κ°μ²΄λ‚˜ non-constructor μ—λŠ” prototype ν”„λ‘œνΌν‹°κ°€ μ—†λ‹€.
console.log(function () {}.hasOwnProperty("prototype")); // true  (ν•¨μˆ˜ κ°μ²΄λŠ” prototype ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ )
console.log({}.hasOwnProperty("prototype")); // false (일반 κ°μ²΄λŠ” prototype ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ ν•˜μ§€ X)