ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ผ๊นŒ?
    ์นดํ…Œ๊ณ ๋ฆฌ ์—†์Œ 2023. 2. 18. 16:51

    Function์— ๋Œ€ํ•œ mdn ๋ฌธ์„œ๋ฅผ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜์™€์žˆ๋‹ค.

    In JavaScript, functions are first-class objects, because they can be passed to other functions, returned from functions, and assigned to variables and properties. They can also have properties and methods just like any other object. What distinguishes them from other objects is that functions can be called.

    "ํ•จ์ˆ˜๋Š” ์ผ๊ธ‰ ๊ฐ์ฒด๋‹ค"๋ผ๋Š” ๋‚ด์šฉ์ด๋ฉฐ, ๋‹ค์Œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๊ฒƒ์„ ์ผ๊ธ‰๊ฐ์ฒด๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

    • ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๊ณ ,
    • ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ,
    • ๋ณ€์ˆ˜๋‚˜ ์ž๋ฃŒ๊ตฌ์กฐ(๊ฐ์ฒด, ๋ฐฐ์—ด ๋“ฑ)์— ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

    ์ถ”๊ฐ€๋กœ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์ฒ˜๋Ÿผ ํ”„๋กœํผํ‹ฐ๋‚˜ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๋ฉฐ, ์ผ๋ฐ˜ ๊ฐ์ฒด์™€๋Š” ๋‹ค๋ฅด๊ฒŒ 'ํ˜ธ์ถœ ๊ฐ€๋Šฅ'ํ•˜๊ธฐ์— ํ•จ์ˆ˜๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค๊ณ  ๋‚˜์™€์žˆ๋‹ค.

    1. ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ

    ํ•จ์ˆ˜๋„ ๊ฐ์ฒด์ด๊ธฐ์— ์ผ๋ฐ˜์ ์ธ ๊ฐ์ฒด์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์„ ์“ธ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ถ”๊ฐ€๋กœ ํ•จ์ˆ˜๋งŒ์˜ ํ‘œ์ฆŒ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค. console.dir๋ฅผ ์ด์šฉํ•˜์—ฌ ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋‚ด๋ถ€๋ฅผ ๋“ค์—ฌ๋‹ค๋ณด์ž.

    ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด, arguments, caller, length, name, prototype ํ”„๋กœํผํ‹ฐ๋Š” ๋ชจ๋‘ ํ•จ์ˆ˜ ๊ฐ์ฒด์˜ ๋ฐ์ดํ„ฐ ํ”„๋กœํผํ‹ฐ๋‹ค. ์ด๋“ค ํ”„๋กœํผํ‹ฐ๋Š” ์ผ๋ฐ˜ ๊ฐ

    ์ฒด์—๋Š” ์—†๋Š” ํ•จ์ˆ˜ ๊ฐ์ฒด ๊ณ ์œ ์˜ ํ”„๋กœํผํ‹ฐ๋‹ค.

    1-1. arguments ํ”„๋กœํผํ‹ฐ

    arguments ๊ฐ์ฒด๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ์ „๋‹ฌ๋œ ์ธ์ˆ˜๋“ค์˜ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” ์ˆœํšŒ๊ฐ€๋Šฅํ•œ(์ดํ„ฐ๋Ÿฌ๋ธ”) ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด์ด๋ฉฐ, ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ง€์—ญ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์‚ฌ์šฉ๋œ๋‹ค.

    arguments ๊ฐ์ฒด๋Š” ์ธ์ˆ˜๋ฅผ ํ”„๋กœํผํ‹ฐ ๊ฐ’์œผ๋กœ ์†Œ์œ ํ•˜๋ฉฐ, ํ”„๋กœํผํ‹ฐ ํ‚ค๋Š” ์ธ์ˆ˜์˜ ์ˆœ์„œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋˜ํ•œ callee ํ”„๋กœํผํ‹ฐ๋Š” ํ˜ธ์ถœ๋˜์–ด arguments ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ ํ•จ์ˆ˜, ์ฆ‰ ํ•จ์ˆ˜ ์ž์‹ ์„ ๊ฐ€๋ฆฌํ‚ค๊ณ , length๋Š” ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

    ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์„ ์–ธ๋œ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ฐœ์ˆ˜์™€ ํ˜ธ์ถœํ•  ๋•Œ ์ „๋‹ฌํ•˜๋Š” ์ธ์ˆ˜์˜ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š๋Š” ํŠน์„ฑ์ด ์žˆ๋Š”๋ฐ, ์ด ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ์ธ์ˆ˜ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•˜๊ณ  ์ด์— ๋”ฐ๋ผ ํ•จ์ˆ˜์˜ ๋™์ž‘์„ ๋‹ฌ๋ฆฌ ์ •์˜ํ•  ํ•„์š”๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋•Œ 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);
    console.log(sum(1,2));
    console.log(sum(1,2,3));

    ์œ ์‚ฌ๋ฐฐ์—ด ๊ฐ์ฒด๋Š” ๋ฐฐ์—ด์ด ์•„๋‹ˆ๋ฏ€๋กœ, ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š”๋ฐ, ์ด ๋•Œ call, bind๋“ฑ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ณ€ํ™˜์˜ ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ES6์—์„œ Rest ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋„์ž…ํ–ˆ๋‹ค.

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

    1-2. caller ํ”„๋กœํผํ‹ฐ

    ํ•จ์ˆ˜์˜ caller ํ”„๋กœํผํ‹ฐ๋Š” ํ•จ์ˆ˜ ์ž์‹ ์„ ํ˜ธ์ถœํ•œ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

    function foo(func){
        return func();
    }
    
    function bar(){
        return 'caller: ' + bar.caller;
    }
    
    // ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ
    console.log(foo(bar)); // caller : function foo(func) {...}
    console.log(bar());    // caller: null

    1-3. length ํ”„๋กœํผํ‹ฐ

    ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•  ๋•Œ ์„ ์–ธํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜ ๊ฐœ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

    function bar(x){
        return x;
    }
    
    console.log(bar.length); // 1
    
    
    const x = (a,b) => a+b;
    console.log(x.length) // 2

    1-3. name ํ”„๋กœํผํ‹ฐ

    ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ต๋ช… ํ•จ์ˆ˜ ํ‘œํ˜„์‹์˜ ๊ฒฝ์šฐ ES5 ์—์„œ๋Š” ๋นˆ ๋ฌธ์ž์—ด์„ ๊ฐ€์กŒ์œผ๋‚˜, ES6๋ถ€ํ„ฐ๋Š” ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์‹๋ณ„์ž๋ฅผ ๊ฐ’์œผ๋กœ ๊ฐ–๋Š”๋‹ค.

    const x = (a,b) => a+b;
    console.log(x.name); // x

    1-4. prototype ํ”„๋กœํผํ‹ฐ

    prototype ํ”„๋กœํผํ‹ฐ๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜ ๊ฐ์ฒด, ์ฆ‰ constructor๋งŒ์ด ์†Œ์œ ํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋‹ค. ์ผ๋ฐ˜ ๊ฐ์ฒด์™€ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์—†๋Š” non-constructor์—๋Š” prototype ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—†๋‹ค.

    // ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” prototype ํ”„๋กœํผํ‹ฐ๋ฅผ ์†Œ์œ ํ•œ๋‹ค.
    (function() {}).hasOwnProperty('prototype'); // true
    
    ({}).hasOwnProperty('prototype'); // false

    prototype ํ”„๋กœํผํ‹ฐ๋Š” ํ•จ์ˆ˜๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ƒ์„ฑ์ž ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ๋  ๋•Œ ์ƒ์„ฑ์ž ํ•จ์ˆ˜๊ฐ€ ์ƒ์„ฑํ•  ์ธ์Šคํ„ด์Šค์˜ ํ”„๋กœํ† ํƒ€์ž… ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค.

    2. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด + a ๋‹ค.

    ํ•จ์ˆ˜๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋Š” ๋ฌผ๋ก , ์œ„์—์„œ ์‚ดํŽด๋ณธ ํ•จ์ˆ˜๋งŒ์˜ ๋‚ด๋ถ€ ์Šฌ๋กฏ๊ณผ ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค.

    ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋“ค์„ ๋‚ด๋ถ€ ์Šฌ๋กฏ์œผ๋กœ ๋‚ด๋ถ€์— ์ถ”๊ฐ€๋กœ ์ €์žฅํ•œ๋‹ค.

    1. ํด๋กœ์ €๋กœ ๋ฌถ์ด๋Š” ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ(Lexical Environment) - [[Environment]]
    2. ํ•จ์ˆ˜ ์ฝ”๋“œ - [[ECMAScriptCode]]
    3. ํ•จ์ˆ˜ ์ข…๋ฅ˜ - [[FunctionKind]]: "normal", "classConstructor", "generator", "async"
    4. ์ƒ์„ฑ์ž ์ข…๋ฅ˜ - [[ConstructorKind]]: "base", "derived"
    5. this ์ฐธ์กฐ ํ˜•ํƒœ - [[ThisMode]]
    6. strict mode ์—ฌ๋ถ€ - [[Strict]]
    7. super ์ฐธ์กฐ - [[HomeObject]]
    8. ๊ธฐํƒ€ ๋“ฑ๋“ฑ

    ๋˜ํ•œ ํ•จ์ˆ˜๊ฐ์ฒด๋Š” [[Call]], [[Constructor]] ๋‚ด๋ถ€ ๋ฉ”์„œ๋“œ๋ฅผ ์ถ”๊ฐ€๋กœ ๊ฐ€์ง„๋‹ค. ๋‹จ์ˆœํ•˜๊ฒŒ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ฐ์ฒด ๋‚ด๋ถ€์˜ [[Call]] ์ด ํ˜ธ์ถœ๋˜๊ณ , new ๋˜๋Š” super ์—ฐ์‚ฐ์ž์™€ ํ•จ๊ป˜ ํ˜ธ์ถœํ•˜๋ฉด [[Constructor]]๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.

    ๋‚ด๋ถ€๋ฉ”์„œ๋“œ [[Call]]์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ callable์ด๋ผ๊ณ  ํ•˜๊ณ , Constructor๊ฐ€ ๊ตฌํ˜„๋œ ๊ฐ์ฒด๋ฅผ constructor๋ผ๊ณ  ๋ถ€๋ฅด๋Š”๋ฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ•จ์ˆ˜๋Š” callable์ด๋ฉด์„œ contructor ์ผ ์ˆ˜๋„ ์žˆ๊ณ  ์•„๋‹ ์ˆ˜๋„ ์žˆ๋‹ค.

    ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ๋‹น์—ฐํ•˜๊ธฐ์—, ๋ชจ๋“  ํ•จ์ˆ˜ ๊ฐ์ฒด๋Š” callable์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ชจ๋“  ํ•จ์ˆ˜๊ฐ€ constructor๋Š” ์•„๋‹ˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” callable์ด๋ฉด์„œ non-constructor์ด๋‹ค. constructor๋กœ ์‚ฌ์šฉํ•˜๋ ค๋ฉด '์ƒ์„ฑ์ž ํ•จ์ˆ˜'๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค.

    • constructor : ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ, ํ•จ์ˆ˜ ํ‘œํ˜„์‹, ํด๋ž˜์Šค (ํด๋ž˜์Šค๋„ ํ•จ์ˆ˜์ด๋‹ค.)
    • non-constructor : ๋ฉ”์„œ๋“œ์˜ ์ถ•์•ฝ ํ‘œํ˜„, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜
    // ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ, ํ•จ์ˆ˜ ํ‘œํ˜„์‹
    function foo(){}
    console.log(new foo());     // foo{}
    
    const bar = function foo(){}
    console.log(new bar());     // bar{}
    
    // ๋ฉ”์„œ๋“œ ์ถ•์•ฝ ๋ฐฉ์‹ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— constructor
    const low = {
     x : function (){}
    }
    console.log(new low.x()));    // x{}
    
    // ํ™”์‚ดํ‘œ ํ•จ์ˆ˜
    const arrow = () => {};
    console.log(arrow);     // () => {}
    console.log(new arrow()) // Uncaught TypeError: arrow is not a constructor
    
    // ๋ฉ”์„œ๋“œ ์ถ•์•ฝ ํ‘œํ˜„
    const obj = {
        x() {}
    }
    console.log(new obj.x()) // Uncaught TypeError: obj.x is not a constructor
    

    ์ฐธ๊ณ 

    ๋Œ“๊ธ€

Designed by Tistory.