In express.js, why is
.Server(app);
valid as a statement?
var http = require('http').Server(app);
Isn't require()
a function, and not an object?
In express.js, why is
.Server(app);
valid as a statement?
var http = require('http').Server(app);
Isn't require()
a function, and not an object?
This method is called chaining/cascading methods.
The require
function returns an Object
, that object
will have a key called Server
which is a function. You can pass parameters to require and Server functions.
A minimal example would be something like this
function require(msg) {
console.log(msg);
return {
"Server": function(msg) {
console.log(msg)
}
}
}
require("require message").Server("some message");
require("Calling only require");
require("Calling require with Server").Server("This is a chained call...");
Isn't require() a function, not an object?
require
is a variable that resolves to a function.
require()
is an expression that evaluates to the return value of calling that function with no arguments.
That return value is, presumably, an object.
The call to the require
function returns an object, of which Server
is a member/field.
require
is a function. But require(...)
can be anything that specific CommonJS module exports with module.exports = ...
.
Also, functions are objects. Even if require(...)
was a function, it could have a property. It is a common recipe for CJS modules in Node.js to provide default export as require(...)
, while named exports can be accessed as properties. In case default export is a function, it is:
function defaultFooExport() {...}
defaultFooExport.namedFooExport = ...;
module.exports = defaultExport;
So it could be imported as:
const foo = require('foo');
const { namedFooExport } = require('foo');
Isn't require() a function, not an object?
Functions are objects in JavaScript:
console.log(function() {} instanceof Object);
Functions actually do have properties themselves, the most well-known being .call
, .apply
and .bind
. So if that is what would be happening, it would still be fine.
However, the code is not trying to access the property Server
of the function require
.
It accesses the property Server
of the value returned by calling require('http')
. That value could be of any type (but it's likely an object). So lets take a quick tour to learn about data types and property access in JavaScript.
There are 7 data types in JavaScript:
The first 6 are so called "primitive" types. As you can see, I didn't list arrays, function, regexes, dates, etc. That's because they are all of type Object. They may have some special internal behavior (e.g. functions are callable) but they are objects nonetheless.
Objects have properties that can be accessed via dot notation:
x.y
However, you can also do "foo".match(...)
, even though "foo"
is actually a primitive value, not an Object. This is possible because JavaScript provides "object wrappers" for the Boolean, Number and String primitive types (that's why we have Boolean
, Number
and String
constructor functions). When you do primitiveValue.something
, primitiveValue
is internally (and temporarily) converted to its Object equivalent.
Only if you are trying to access a property on a value that cannot be converted to an object will the access fail.
var foo = null;
foo.bar;
Today, I try to fix javascript error about our project, many error cause by null or undefined value. for example
Cannot read property 'render' of null
Cannot read property 'message' of undefined
o.size is not a function
require('xxx'), if you don't know its return, make judgments before use. for example:
attribute
if(res){
console.log(res.message);
//....your statement.....
}
function
if(o && o.size){
console.log(o.size());
//....your statement.....
}
There are several ways to accomplish the module pattern in java script like 'Anonymous closure’, 'Global import like in JQuery Module', CommonJS required, AMD UMD etc. So when we use the module through import or require we internally get the reference to the object. Once we get the object we invoke the method in the object through '.' operator. So in case of "var http = require('http').Server(app);" we are first creating the object reference in var http and then we are invoking method "Server(app)" present in that object by passing app as parameter. Writing Modular JavaScript With AMD, CommonJS & ES Harmony is good article to understand more what is requires and how it works.