🐸 [JavaScript] ν•¨μˆ˜μ™€ 일급 객체

hnyoojinΒ·2024λ…„ 9μ›” 17일

🐸 JS λ§ˆμŠ€ν„° 되기

λͺ©λ‘ 보기
17/19
post-thumbnail

λ­”κ°€ μ½”λ“œλ‘œ κ³΅λΆ€ν•˜λŠ” 게 μ’€ 더 잘 μ™€λ‹ΏλŠ” κΈ°λΆ„μ΄λΌμ„œ,, 이번 κΈ€ λΆ€ν„°λŠ” μ½”λ“œ 폭탄 ν¬μŠ€νŠΈκ°€ 될 것 κ°™λ‹€..γ…Žγ…Ž


일급 객체

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

// 1. ν•¨μˆ˜λŠ” 무λͺ…μ˜ λ¦¬ν„°λŸ΄μ— μ €μž₯ν•  수 μžˆλ‹€.
// 2. ν•¨μˆ˜λŠ” λ³€μˆ˜μ— μ €μž₯ν•  수 μžˆλ‹€. 
// runtime에 ν•¨μˆ˜ λ¦¬ν„°λŸ΄μ΄ ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체가 μƒμ„±λ˜κ³ , λ³€μˆ˜μ— ν• λ‹Ήλœλ‹€.
const increase = function (num) {
    return ++num;
};

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

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

// 3. ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜μ— 전달할 수 μžˆλ‹€.
// 4. ν•¨μˆ˜μ˜ λ°˜ν™˜κ°’μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
function makeCounter(aux) {
    let num = 0;

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

// 3. ν•¨μˆ˜λŠ” λ§€κ°œλ³€μˆ˜μ— ν•¨μˆ˜λ₯Ό 전달할 수 μžˆλ‹€.
const increaser = makeCounter(auxs.increase);
console.log(increaser()); // 1
console.log(increaser()); // 2

// 3. ν•¨μˆ˜λŠ” λ§€κ°œλ³€μˆ˜μ—κ²Œ ν•¨μˆ˜λ₯Ό 전달할 수 μžˆλ‹€.
const decreaser = makeCounter(auxs.decrease);
console.log(decreaser()); // -1
console.log(decreaser()); // -2

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

function square(number) {
    return number * number;
}

// console.dir : ν•¨μˆ˜ 객체의 λ‚΄λΆ€λ₯Ό λ“€μ—¬λ‹€λ³΄λŠ” λ©”μ„œλ“œ
console.dir(square); // [Function: square]

------------------------------------------
// λͺ¨λ“  property의 property attributeλ₯Ό ν™•μΈν•˜λŠ” λ©”μ„œλ“œ
console.log(Object.getOwnPropertyDescriptors(square));

function square(number) {
    return number * number;
}

// __proto__λŠ” square ν•¨μˆ˜μ˜ ν”„λ‘œνΌν‹°κ°€ μ•„λ‹ˆλ‹€.
console.log(Object.getOwnPropertyDescriptor(square, '__proto__')); // undefined

// __proto__λŠ” Object.prototype 객체의 μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ‹€.
// square ν•¨μˆ˜λŠ” Object.prototype κ°μ²΄λ‘œλΆ€ν„° __proto__ μ ‘κ·Όμž ν”„λ‘œνΌν‹°λ₯Ό μƒμ†λ°›λŠ”λ‹€.
console.log(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'));

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

function multiply (x, y) {
    console.log(arguments);
    return x * y;
}

console.log(multiply());
console.log(multiply(1));
console.log(multiply(1, 2));
console.log(multiply(1, 2, 3));

- arguments 객체의 Symbol(Symbol.iterator) ν”„λ‘œνΌν‹°

function multiply (x, y) {
  	// μ΄ν„°λ ˆμ΄ν„°
    const iterator = arguments[Symbol.iterator]();

  	// μ΄ν„°λ ˆμ΄ν„°μ˜ next λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜μ—¬ μ΄ν„°λŸ¬λΈ” 객체 argumentsλ₯Ό 순회
    console.log(iterator.next());
    console.log(iterator.next());
    console.log(iterator.next());
  	console.log(iterator.next());

    return x + y;
}

multiply(1, 2, 3);

JSμ—μ„œλŠ” μ„ μ–Έλœ λ§€κ°œλ³€μˆ˜μ˜ κ°œμˆ˜μ™€, ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ–Ό μ „λ‹¬ν•˜λŠ” 인수의 개수λ₯Ό ν™•μΈν•˜μ§€ μ•ŠλŠ”λ‹€.
그런데 ν•¨μˆ˜κ°€ 호좜되면, 인수의 개수λ₯Ό ν™•μΈν•œ λ‹€μŒ, 이에 따라 ν•¨μˆ˜μ˜ λ™μž‘μ„ 달리 μ •μ˜ν•  ν•„μš”κ°€ μžˆμ„μˆ˜λ„ μžˆλ‹€.

이 λ•Œ arguments 객체가 μœ μš©ν•˜κ²Œ μ‚¬μš©λœλ‹€.

function sum() {
    let res = 0;

    // arguments κ°μ²΄λŠ” length ν”„λ‘œνΌν‹°κ°€ μžˆλŠ” μœ μ‚¬ λ°°μ—΄ 객체.
    // for문으둜 순회 κ°€λŠ₯ν•˜λ‹€.
    for (let i=0; i < arguments.length; i++){
        res += arguments[i];
    }

    return res;
}

console.log(sum());         // 0
console.log(sum(1, 2));     // 3
console.log(sum(1, 2, 3));  // 6
// ν•˜μ§€λ§Œ argumentsλŠ” μ–΄λ””κΉŒμ§€λ‚˜ μœ μ‚¬ λ°°μ—΄ 객체이닀.
// 배열은 μ•„λ‹ˆλ―€λ‘œ, λ°°μ—΄ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ errorκ°€ λ°œμƒν•œλ‹€.

function sum() {
  	// κ·Έλž˜μ„œ Function.prototype.call, Function.prototype.apply λ₯Ό 톡해 κ°„μ ‘ ν˜ΈμΆœν•΄μ•Ό 함
    const array = Array.prototype.slice.call(arguments);
    return array.reduce(function (pre, cur) {
        return pre + cur;
    }, 0);
}

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


// => 맀번 κ°„μ ‘ ν˜ΈμΆœν•˜κΈ°λŠ” λ„ˆλ¬΄ λ²ˆκ±°λ‘œμ›€!!
// κ·Έλž˜μ„œ ES6 μ—μ„œλŠ”, Rest νŒŒλΌλ―Έν„°λ₯Ό λ„μž…ν•¨

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

console.log(sum(1, 2));
console.log(sum(1, 2, 3, 4, 5));

- caller ν”„λ‘œνΌν‹°

  • ECMAScript μ‚¬μ–‘μ—λŠ” ν¬ν•¨λ˜μ§€ μ•ŠμŒ
function foo(func) {
    return func();
}

function bar() {
    return 'caller : ' + bar.caller;
}

// λΈŒλΌμš°μ €μ—μ„œμ˜ μ‹€ν–‰ν•œ κ²°κ³Ό
console.log(foo(bar));
console.log(bar());


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

  • ν•¨μˆ˜λ₯Ό μ •μ˜ν•  λ•Œ μ„ μ–Έν•œ λ§€κ°œλ³€μˆ˜μ˜ 개수λ₯Ό 가리킴
  • arguments 객체와 ν•¨μˆ˜ 객체의 length ν”„λ‘œνΌν‹° 값은 λ‹€λ₯Ό 수 μžˆλ‹€.
    • arguments : 인수의 개수
    • ν•¨μˆ˜ : 맀개 λ³€μˆ˜μ˜ 개수
function foo() {}
console.log(foo.length);  // 0

function bar(x) {
    return x;
}
console.log(bar.length);  // 1

function baz(x, y) {
    return x * y;
}
console.log(baz.length);  // 2

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

  • ν•¨μˆ˜ 객체의 name ν”„λ‘œνΌν‹°λŠ”, ν•¨μˆ˜μ˜ 이름을 λ‚˜νƒ€λƒ„
  • ES6λΆ€ν„° ν‘œμ€€μ΄ 됨 (κ·Έ μ „μ—λŠ” λΉ„ν‘œμ€€)
    • 읡λͺ… ν•¨μˆ˜ ν‘œν˜„μ‹μ˜ 경우
      • ES5 : 빈 λ¬Έμžμ—΄μ„ κ°’μœΌλ‘œ 가짐
      • ES6 : ν•¨μˆ˜ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” μ‹λ³„μžλ₯Ό κ°’μœΌλ‘œ 가짐
var namedFunc = function foo() {};
console.log(namedFunc.name);     // foo

var anonymousFunc = function() {};
console.log(anonymousFunc.name); // anonymousFunc

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

- __proto__ ν”„λ‘œνΌν‹°

  • λͺ¨λ“  κ°μ²΄λŠ” [[Prototype]]μ΄λΌλŠ” λ‚΄λΆ€ μŠ¬λ‘―μ„ 가짐
  • __proto__ : μ ‘κ·Όμž ν”„λ‘œνΌν‹°
    • [[Prototype]] λ‚΄λΆ€ 슬둯이 κ°€λ¦¬ν‚€λŠ” ν”„λ‘œν† νƒ€μž… 객체에 μ ‘κ·Όν•˜κΈ° μœ„ν•΄,,,
const obj = { a: 1 };

// Object.prototype : 객체 λ¦¬ν„°λŸ΄ λ°©μ‹μœΌλ‘œ μƒμ„±ν•œ 객체의 ν”„λ‘œν† νƒ€μž… 객체
console.log(obj.__proto__ === Object.prototype);

// 객체 λ¦¬ν„°λŸ΄ λ°©μ‹μœΌλ‘œ μƒμ„±ν•œ κ°μ²΄λŠ” ν”„λ‘œν† νƒ€μž… 객체인 Object.prototype의 ν”„λ‘œνΌν‹°λ₯Ό μƒμ†λ°›μŒ
// hasOwnProperty λ©”μ„œλ“œ : Object.prototype의 λ©”μ„œλ“œ
console.log(obj.hasOwnProperty('a'));
console.log(obj.hasOwnProperty('__proto__'));


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

  • μƒμ„±μž ν•¨μˆ˜λ‘œ ν˜ΈμΆœν•  수 μžˆλŠ” 객체만이 μ†Œμœ ν•˜λŠ” ν”„λ‘œνΌν‹°
    • constructor만이 μ†Œμœ  κ°€λŠ₯
  • 일반 객체, non-constructorμ—λŠ” protytype ν”„λ‘œνΌν‹°κ°€ μ—†μŒ

ν™•μ‹€νžˆ μ½”λ“œλ₯Ό 직접 μ†μœΌλ‘œ μ³λ³΄λ‹ˆκΉŒ, '였 κ·ΈλŸ¬λ„€' μ •λ„μ˜ 이해라도 κ°€λŠ₯ν•œ 것 κ°™λ‹€.

μ•žμœΌλ‘œλ„ μ΄λ ‡κ²Œ 곡뢀λ₯Ό 해봐야겠닀..!

0개의 λŒ“κΈ€