0

I have read couple of posts on SO before posting this question. One thing that's not clear to me is why I'm not able to use multiply function when importing this as module. Isn't module.exports and exports refer to the same object?

Shouldn't multiply be added to the object that is referenced by module.exports. Since exports is an alias for module.exports, I was expecting I'm adding multiply to the same object as I'm not reassigning exports to refer to something else.

module.exports = {
  sum : function(a,b){
    return a+b;
  }
};

exports.multiply = function(a,b){
  return a*b;
};
Mahtab Alam
  • 1,810
  • 3
  • 23
  • 40

2 Answers2

1

Note that at the start of each nodejs module file, both exports and module.exports point at the same empty object. And you can assign properties to them like below:

exports.item1 = "hi1"

module.exports.item2 = "hi2"

Now both of the exports and module.exports have the same value:

{item1:"hi1", item2: "hi2"}

But when you assign objects to them, only the object that you have given to module.exports matters! In your case if you want to assign an object to module.exports and then add other functions to it, you should first assign the same object to both of them! Now they will point to the same object and if you assign another function to your exports object, it will be accessible via module.exports object, too.

Change the first line of your code and it will work fine!

exports = module.exports = {
    sum : function(a,b){
    return a+b;
    }
};

exports.multiply = function(a,b){
    return a*b;
};
tashakori
  • 2,331
  • 1
  • 22
  • 29
  • But according to this, var exports = module.exports, isn't exports and module.exports point to same object. – Mahtab Alam Jul 09 '17 at 05:01
  • at first line segment of code we are assigning an object containing sum=function(){...} to both "exports" and "module.exports". then we are adding another function(multiply) as a property to the same object. – tashakori Jul 09 '17 at 05:10
  • test case: save the above code as m.js then in another file write this: var m = require("./m.js") console.log(m.sum(1,2)) console.log(m.multiply(1,2)) it will work just as expected. – tashakori Jul 09 '17 at 05:11
0

You cannot access the multiply function because javascript objects are passed by reference. When you use the line module.exports = {blah}, you create a new object {blah} and set module.exports to point at it. However, exports still points to the old object.

Initially, module.exports and exports point to the same empty object. So, exports = {} , module.exports = {}. But when you create a new object and have module.exports point at it, Eg:

module.exports = {
  sum : function(a,b){
    return a+b;
  }
};

module.exports will point at the new object, but exports will still point at the old object:

// exports will still point to the old object
console.log(exports) // prints {}
console.log(module.exports) // prints { sum: function() }

Then:

console.log(exports) // prints {}
exports.multiply = function(a,b){
    return a*b;
};
console.log(exports) // prints { multiply: function() }

When you import the module, you are returned the value in module.exports, so you won't have access to the multiply function, since that was defined in exports, which references a different object.

If you don't want to worry about this issue, you can just do:

exports = module.exports = {
  sum : function(a,b){
    return a+b;
  }
};

This will make them reference the same object. Hence,

exports.multiply = function(a,b){
    return a*b;
};

will work as normal.

keithlee96
  • 1,724
  • 2
  • 11
  • 17