1

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?

7
  • 6
    require is a function, but it returns an object. Commented Sep 28, 2018 at 8:10
  • As @Teemu said, 'require' returns object. Here, written in order or chain method var http = require('http').Server(app); This just means, var http = require('http'); var server = http.Server(app); Commented Sep 28, 2018 at 8:12
  • 1
    what Teemu said, and if you want read up on the topic you might want to look up "method chaining" Commented Sep 28, 2018 at 8:13
  • Possible duplicate of Javascript chaining methods and processing time Commented Sep 28, 2018 at 8:13
  • 2
    Additionally: it might be a bit confusing that Serveris written in uppercase - that is against JS style for a normal function. I think the express guys did so to highlight that the Server() call returns the server object and effectively serves as its constructor Commented Sep 28, 2018 at 8:15

7 Answers 7

2

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...");

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

The call to the require function returns an object, of which Server is a member/field.

Comments

0

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');

Comments

0

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.


Data types

There are 7 data types in JavaScript:

  • Boolean
  • Number
  • String
  • Null
  • Undefined
  • Symbol
  • Object

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.

Property access

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;

Comments

0

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.....
}

Comments

-1

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.