Given my code
const express = require(\"express\")
const app = express()
console.log(typeof app)
console.log(typeof express)
My terminal tell
when I require “express” I need to know if its an object or function
It's both. Functions in Javascript are objects.
Without getting technical, express
is a factory function that creates an app instance and app
is an express instance. Now, technically, both express
and app
are functions. But, functions in Javascript are objects and can have properties. The express object has static properties. The app
object behaves much like an instance of the express class. It has both methods and instance data.
Now, getting a little more technical...
const express = require('express')
gets you a function and that function is also an object and has properties.
This specific function is a factory function that creates an app
object when you call it that is also a function that has properties.
So, express
also has properties that can be used such as:
express.static
express.json
express.urlencoded
And, it can be called as in:
const app = express();
Likewise, app
is a function that has properties too. It can be used as a function as in:
const server = http.createServer(app);
server.listen(80);
Or, it can be used like an object as in:
const server = app.listen(80);
If you output this:
console.log(typeof express);
console.log(typeof app);
You will see this:
function
function
They are both functions. But, functions in Javascript are objects too and can have properties.
So, you can do things like this:
function myFunction() {
return "ok";
}
myFunction.greeting = "Hello";
console.log(myFunction()); // "ok"
console.log(myFunction.greeting); // "Hello"
Looking further at both express
and app
, if you did this:
console.log(Object.getOwnPropertyNames(express));
You would get this:
[
'length', 'name',
'prototype', 'application',
'request', 'response',
'Route', 'Router',
'json', 'query',
'raw', 'static',
'text', 'urlencoded',
'bodyParser', 'compress',
'cookieSession', 'session',
'logger', 'cookieParser',
'favicon', 'responseTime',
'errorHandler', 'timeout',
'methodOverride', 'vhost',
'csrf', 'directory',
'limit', 'multipart',
'staticCache'
]
And, this:
console.log(Object.getOwnPropertyNames(app));
would get this:
[
'length', 'name', 'prototype',
'constructor', '_events', '_eventsCount',
'_maxListeners', 'setMaxListeners', 'getMaxListeners',
'emit', 'addListener', 'on',
'prependListener', 'once', 'prependOnceListener',
'removeListener', 'off', 'removeAllListeners',
'listeners', 'rawListeners', 'listenerCount',
'eventNames', 'init', 'defaultConfiguration',
'lazyrouter', 'handle', 'use',
'route', 'engine', 'param',
'set', 'path', 'enabled',
'disabled', 'enable', 'disable',
'acl', 'bind', 'checkout',
'connect', 'copy', 'delete',
'get', 'head', 'link',
'lock', 'm-search', 'merge',
'mkactivity', 'mkcalendar', 'mkcol',
'move', 'notify', 'options',
'patch', 'post', 'propfind',
'proppatch', 'purge', 'put',
'rebind', 'report', 'search',
'source', 'subscribe', 'trace',
'unbind', 'unlink', 'unlock',
'unsubscribe', 'all', 'del',
'render', 'listen', 'request',
'response', 'cache', 'engines',
'settings', 'locals', 'mountpath',
'router'
]
So, you can see they each have a lot of properties in addition to being functions.
Ok please tell me if I have got this correct. 1) When I do this…
const express = require(“express”)
I store a “Class” into the express variable. 2) Then when I do this…express.json()
I am accessing thejson()
function inside the express class ?
As I said in my answer above that express
variable represents a factory function. That's a function that, when called, creates an object for you. It's a different way of creating an object from directly calling a constructor as in new myObj()
. express.json
is a function that, when called, creates a middleware function for you that uses the parameters you passed the function.
The Express architecture differs a bit from a pure class style architecture. It uses a factory function that creates an instance (essentially of a class). And, then the app
represents that instance, but also works as a request handler on its own.