생성자 함수 createApplication(2)

김대웅·2021년 6월 22일
0

express 분석

목록 보기
2/14

node.js의 express.js 한줄 한줄 분석하고 있습니다.

express/lib/express.js

var EventEmitter = require('events').EventEmitter;
var mixin = require('merge-descriptors');

function createApplication() {
  var app = function(req, res, next) {
    app.handle(req, res, next);
  };

  /**
   * merge-descriptors의 경우 두번째 인자의 프로퍼티를 첫번째 인자의 프로퍼티로 복사해줌
   * 세번째 인자가 true인 경우 첫번째 인자에 이미 존재하는 프로퍼티를 두번째 인자의 프로퍼티로 덮어 씌움
   */

  mixin(app, EventEmitter.prototype, false);
  /**
   * EventEmitter란?
   *
   * https://edykim.com/ko/post/events-eventemitter-translation-in-node.js/ https://stickie.tistory.com/66 참고
   *
   * 노드에서는 대부분의 이벤트를 비동기 방식으로 처리
   * EventEmitter는 이벤트를 보내고 받을수 있는 기능을 가지고 있음
   *
   */

  /**
   * EventEmitter.prototype에서 app에 복사한 프로퍼티
   *
   * _events
   * _eventsCount
   * _maxListeners
   * setMaxListeners
   * getMaxListeners
   * emit
   * addListener
   * on
   * prependListener
   * once
   * prependOnceListener
   * removeListener
   * off
   * removeAllListeners
   * listeners
   * rawListeners
   * listenerCount
   * eventNames
   *
   */

  /**
   * 현재 express에서 사용중인것으로 추정되는 메소드
   *
   * emit -> 등록한 이벤트를 호출
   * on -> 리스너 등록시 사용
   *
   */

  /**
   * EventEmitter를 상속받지 않은 이유
   *
   * app의 경우 함수이므로 EventEmitter를 상속받기보다는 필요한 프로퍼티를 복사하는것이 더 나을것으로 추정
   *
   */

  /**
   * express에서 EventEmitter의 프로퍼티를 복사하는 이유
   *
   * 비동기적인 이벤트 처리를 위해 복사하는것으로 추정
   */

  mixin(app, proto, false);


  // expose the prototype that will get set on requests
  app.request = Object.create(req, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  // expose the prototype that will get set on responses
  app.response = Object.create(res, {
    app: { configurable: true, enumerable: true, writable: true, value: app }
  })

  app.init();
  return app;
}

merge-descriptors

/*!
 * merge-descriptors
 * Copyright(c) 2014 Jonathan Ong
 * Copyright(c) 2015 Douglas Christopher Wilson
 * MIT Licensed
 */

'use strict'

/**
 * Module exports.
 * @public
 */

module.exports = merge

/**
 * Module variables.
 * @private
 */

var hasOwnProperty = Object.prototype.hasOwnProperty
/**
 * Object.create(null)을 통해 개체를 만든경우 데이터 타입은 개체이지만 prototype이 undefined로 설정이 됨
 * 따라서 hasOwnProperty()함수에 접근할 수 없다.
 *
 * 또한 자바스크립트의 경우 hasOwnProperty 프로퍼티를 보호하지 않는다.
 * 따라서 해당 프로퍼티를 얼마든지 수정할 수 있다.
 *
 * https://stackoverflow.com/questions/12017693/why-use-object-prototype-hasownproperty-callmyobj-prop-instead-of-myobj-hasow 참고
 */

/**
 * hasOwnProperty : 개체가 특정 프로퍼티를 소유하고 있는지 판단하는데 사용한다. / 개체의 프로토타입 체인을 확인하지 않는다.
 */

/**
 * Merge the property descriptors of `src` into `dest`
 *
 * @param {object} dest Object to add descriptors to
 * @param {object} src Object to clone descriptors from
 * @param {boolean} [redefine=true] Redefine `dest` properties with `src` properties
 * @returns {object} Reference to dest
 * @public
 */

function merge (dest, src, redefine) {
  if (!dest) {
    throw new TypeError('argument dest is required')
  }

  if (!src) {
    throw new TypeError('argument src is required')
  }

  if (redefine === undefined) {
    // Default to true
    redefine = true
  }
  /**
   * merge-descriptors함수를 사용하기 위해서는 기본적으로 인자 두개를 넣어주어야함
   * redefine의 경우 디폴트 값은 true로 설정한다.
   */

  /**
   * src에 있는 프로퍼티가 dest에도 있는경우
   * redefine이 true이면 src에 있는 프로퍼티를 dest로 복사한다.
   * redefine이 false이면 src에 있는 프로퍼티를 dest로 복사하지 않는다.
   */

  Object.getOwnPropertyNames(src).forEach(function forEachOwnPropertyName (name) {
    if (!redefine && hasOwnProperty.call(dest, name)) {
      /**
       * Function.prototype.call : 첫번째 매개변수를 this, 나머지 매개변수를 인수로 하여 함수를 호출한다.
       */
      // Skip descriptor
      return
    }
    /**
     * redefine이 false이고 dest에 src의 프로퍼티와 동일한 프로퍼티가 있는경우
     * 복사를 하지 않는다.
     */

    // Copy descriptor
    var descriptor = Object.getOwnPropertyDescriptor(src, name)
    /**
     * Object.getOwnPropertyDescriptor : 주어진 개체의 프로퍼티에 대한 속성 설명자(descriptor)를 반환한다.
     */
    Object.defineProperty(dest, name, descriptor)
    /**
     * Object.defineProperty : 개체에 직접 새로운 속성을 정의하거나 이미 존재하는 속성을 수정한 후, 그 개체를 반환한다.
     */
    /**
     * src의 프로퍼티를 dest에 복사한다.
     */
  })

  return dest
}

https://github.com/JsTsPractices/express/commit/e7c9be5eede3286ff52b7d06e6239f56ed9af7f3

profile
42seoul cadet

0개의 댓글