[study] 언제까지 넘겨 짚을래 ch18. 함수와 일급객체

가오리·2023년 4월 27일
0

javascript

목록 보기
16/44
post-thumbnail
📌 스터디 교재 및 강의
  1. [youtube] 모던 자바스크립트 Deep Dive 스터디
  2. [e-book] 모던 자바스크립트 Deep Dive
  3. [e-book] 코어 자바스크립트
  4. [blog] 자바스크립트 개발자라면 알아야 할 33가지 개념

✏️ 일급 객체

일급객체 조건

  1. 무명의 리터럴로 생성할 수 있다. → 런타임에 생성이 가능하다.
  2. 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.
  3. 함수의 매개변수에 전달할 수 있다.
  4. 함수의 반환값으로 사용할 수 있다.
// 1, 2
const plus = function (number) {
  return ++number;
};

const minus = function (number) {
  return --number;
};

// 2
const calculator = { plus, minus };

// 3, 4
function makeCalculator(calculator) {
  let number = 0;
  return function () {
    number = calculator(number);
    return number;
  };
}

// 3
const increase = makeCalculator(calculator.plus);
console.log(increase()); // 1
const decrease = makeCalculator(calculator.minus);
console.log(decrease()); // -1

✏️ 함수 객체의 프로퍼티

함수도 객체이기 때문에 프로퍼티를 가질 수 있고 함수의 모든 프로퍼티의 프로퍼티 어트리뷰트는 Object.getOwnPropertyDescriptors 메서드를 통해 알 수 있다.

function double(number) {
  return number * 2;
}
console.log(Object.getOwnPropertyDescriptors(double));
/* 
{
  length: { value: 1, writable: false, enumerable: false, configurable: true },
  name: { value: 'double', writable: false, enumerable: false,  configurable: true },
  arguments: { value: null, writable: false, enumerable: false, configurable: false },
  caller: { value: null, writable: false, enumerable: false, configurable: false },
  prototype: { value: {}, writable: true, enumerable: false, configurable: false }
} */
  1. arguments 프로퍼티

    함수 객체의 arguments 프로퍼티 값은 arguments 객체이고 이 객체는 함수 호출 시 전달된 인수들의 정보를 담고 있는 순회 가능한 유사 배열 객체이며 함수 내부에서 지역변수처럼 사용된다.

    자바스크립트는 함수의 매개변수와 인수의 개수가 일치하는지 확인하지 않기 때문에 에러가 발생하지 않고 인수가 적을 경우 undefined로 초기화된 상태를 유지하고 인수가 많을 경우 초과된 인수는 무시되는데 초과된 인수는 버려지지 않고 arguments 객체의 프로퍼티로 보관된다.

    function plus(a, b) {
      console.log(arguments);
      return a + b;
    }
    console.log(plus());        // [Arguments] {} | NaN
    console.log(plus(1));       // [Arguments] { '0': 1 } | NaN
    console.log(plus(1, 2));    // [Arguments] { '0': 1, '1': 2 } | 3
    console.log(plus(1, 2, 3)); // [Arguments] { '0': 1, '1': 2, '2': 3 } | 3 

    매개변수를 확정할 수 없는 가변 인자 함수 구현 시 유용하고 arguments 객체는 length 프로퍼티가 있는 유사 배열 객체이므로 for문으로 순회할 수 있다.

    function sum() {
      let res = 0;
      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
  2. length 프로퍼티

    함수를 정의할 때 선언한 매개변수의 개수

    function noArg() {}
    function oneArg(x) {
      return x;
    }
    function twoArg(x, y) {
      return x + y;
    }
    
    console.log(noArg.length);  // 0
    console.log(oneArg.length); // 1
    console.log(twoArg.length); // 2
  3. name 프로퍼티

    함수 이름을 나타내는데 ES5와 ES6가 다르게 동작한다. 좀 더 자세히 설명하자면 익명함수 표현식의 경우 ES5는 빈 문자열 값으로, ES6는 함수 객체를 가리키는 식별자를 값으로 가진다.

    var namedFunc = function foo() {};
    var anonymousFunc = function () {};
    function bar() {}
    console.log(namedFunc.name);     // 기명 함수 표현식: foo
    console.log(anonymousFunc.name); // 익명 함수 표현식: anonymousFunc
    console.log(bar.name);           // 함수선언문: bar
  4. proto 접근자 프로퍼티

    모든 객체는 [[Prototype]]이라는 내부 슬롯을 가지는데 [[Prototype]]내부 슬롯은 객체지향 프로그래밍의 상속을 구현하는 프로토타입 객체를 가리킨다.

    proto 프로퍼티는 [[Prototype]] 내부 슬롯이 가지는 프로토타입 객체에 간접적으로 접근하기 위해 사용하는 접근자 프로퍼티이다.

    🪝 hasOwnProperty 메서드: 인수로 전달받은 프로퍼티 키가 객체 고유의 프로퍼티 키인 경우에만 true를 반환하고 상속받은 프로토타입의 프로퍼티 키인 경우 false를 반환한다.

    const obj = { x: 1 };
    console.log(obj.__proto__ === Object.prototype); // true
    
    console.log(obj.hasOwnProperty('a'));       // false
    console.log(obj.hasOwnProperty('__proto')); // false
  5. prototype 프로퍼티

    생성자 함수로 호출할 수 있는 함수 객체, constructor만이 소유하는 프로퍼티이며 일반 객체와 생성자 함수로 호출할 수 없는 non-constructor에는 prototype 프로퍼티가 없다.

    console.log(function () {}.hasOwnProperty('prototype')); // true
    console.log({}.hasOwnProperty('prototype')); // false

🧩 순수함수

자바스크립트 개발자라면 알아야 할 33가지 개념 #20 자바스크립트: 순수함수

  1. 같은 입력값이 들어왔을 때, 항상 같은 출력이 나온다.

    function double(number) {
      return number * 2;
    }
    
    console.log(Math.random()); // 0.713656697021601
    console.log(Math.random()); // 0.9997548358011055
    
    console.log(double(2)); // 4
    console.log(double(2)); // 4

    double() 메소드는 같은 입력값이 들어왔을 때 항상 같은 출력값이 나온다. 하지만 Math.random()은 0~1 사이의 새로운 랜덤 넘버를 생성하는데 이 함수는 순수하지 않다.

  2. side-effect를 갖지 않는다.

    순수 함수는 어떤 side-effect도 만들지 않는다. 쉽게 말하자면 어떤 외부 상태도 변환하지 않는다는 것을 의미한다.

profile
가오리의 코딩일기

0개의 댓글