4

Hey I was wondering why the following returns undefined:

let variable;

module.exports.initialize = () => {
  variable = "123";
};

module.exports.variable = variable;


I simply require the module in file A and then call the initialize function. In file B I require it and console.log the variable but it returns undefined. What am I missing here?

3
  • Well obviously you never called initialize() before you exported the variable's value? Commented Feb 13, 2022 at 1:41
  • @Bergi I have in file A, which I didn't include for simplicity purposes. Commented Feb 13, 2022 at 1:44
  • But you call that after the value undefined has been exported Commented Feb 13, 2022 at 1:45

3 Answers 3

6

In JavaScript there are two types of values: 1) primitive type and 2) reference type. primitive values are always copied by their value and reference types are always copied by their references (not by their values).

Examples of primitive values: undefined, null, boolean, string, number. Examples of reference types: every types other than primitive types. e.g., Object, array etc. See the snippet below.

Example of Primitive type

let a = 10;
let b = a;

console.log(a);
console.log(b);

b = 20;

console.log(a);
console.log(b);

Example of Reference type

let obj_a = {value: 1}
let obj_b = obj_a;

console.log(obj_a);
console.log(obj_b);

obj_b.value = 20;

console.log(obj_a);
console.log(obj_b);

So when you declare the variable as let variable its value is undefined and when you assign module.exports.variable = variable then you're just setting it's value to undefined.

See the example below.

const myExports = {};

let variable;

function initialize() {
  variable = 10;
}

myExports.variable = variable;

console.log(variable);
console.log(myExports.variable);

initialize();

console.log(variable);
console.log(myExports.variable);

But if you were to initialize the the variable with a reference type e.g., an object then module.exports.variable would reflect any change to the properties of your variable variable.

Example:

const myExports = {};

let object = {};

function initialize() {
  object.value = 10;
}

myExports.variable = object;

console.log(object);
console.log(myExports.variable);

initialize();

console.log(object);
console.log(myExports.variable);

Hope it make sense.

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

Comments

2

module.exports.variable is a property on the module.exports object. When you initialize your module, you assign the value of variable to that module.exports.variable property and that value is undefined at the time you assign it (because the initialize() function has not yet been called).

So, when your module is done initializing itself, module.exports.variable is undefined.

Then, sometime later someone else calls module.exports.initialize() and that changes the local variable within your module to "123". That does not affect the value of the module.exports.variable property at all. It remains undefined.

In the future, please don't give either a property or a variable the name variable as it makes it very difficult to document or discuss. A different name that doesn't conflict with the English definition of the word variable would simplify discussing this code.


What you can do instead is export an object instead of a plain value.

let myObj = { name: "John"};

module.exports.setName = (name) => {
  myObj.name = name;
};

module.exports.sharedObj = myObj;

Then, why you import it somewhere else

const aModule = require('./otherModule');
console.log(aModule.sharedObj);         // {name: "John"}

aModule.setName("Bob");
console.log(aModule.sharedObj);         // {name: "Bob"}

Because objects in Javascript are assigned by pointer, when you did module.exports.sharedObj = myObj; in the module initialization, it put a pointer to myObj into module.exports.sharedObj so when myObj changes, anyone viewing module.exports.sharedObj will see that change too. This only works this way for objects in Javascript, not for other types of values (strings, numbers, etc...).

3 Comments

I agree, perhaps I should've called it something else. However how do I chang e the 'variable' I'm trying to export in the initialize function?
I saw your update, thanks a lot! What about: module.exports.variable = "123"; inside the initialize function, thats a lot shorter and does not need an object at all and is shorter
@sharpness - Doing module.exports.variable = "123" can work, but you will have to be careful about how you import it. If you do this: let myVar = require('./otherModule').variable;, then myVar will never change. If you import it as const myModule = require('./otherModule') and then examine myModule.variable, then it will work. The key is that you have to be saving the containing object and referencing the property off that containing object.
-2

try initializing the variable in the module.exports.initailize function

module.exports.initialize = () => {
    let variable;
    variable = "123";
};



module.exports.variable = variable;

1 Comment

Now that will even throw an exception in strict mode, not just export undefined.

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.