1

I create a module with following

module.exports = {
    GetRandomNum:(Min,Max)=>{
        var Range = Max - Min;   
        var Rand = Math.random();   
        return(Min + Math.round(Rand * Range)); 
    },
    mathCalculationtion:()=>{
        var firstPlace = this.GetRandomNum(1, 9);
        return firstPlace;
    }
}

I run this above code and get an error at the line var firstPlace = this.GetRandomNum(1, 9);

at Object. mathCalculationtion (/home/sfud/projectland/lib/comlib.js)

Please help me, thank you.

Bin
  • 468
  • 1
  • 5
  • 18
  • of course not, this is not a class instance, it's just a primitive object. There is not `this` context. If you want to use `this`, declare a class and export that instead, or set up a ES5 style constructor and then assign a prototype (which would be a weird thing to do now that we have class syntax) – Mike 'Pomax' Kamermans Jul 26 '20 at 01:48
  • Please look at the arrow functions, when to use. https://stackoverflow.com/questions/22939130/when-should-i-use-arrow-functions-in-ecmascript-6/40062077#40062077 – Thalaivar Jul 26 '20 at 01:51
  • @Mike'Pomax'Kamermans That's actually not true at all. `this` exists whenever a function is called using the `.` syntax (unless it is bound to `null` or `undefined`), and exists whenever `bind()` is called on the function. You can also use `myFunc.apply()` and `myFunc.call()` but while those are *possible* here, they're not very helpful. – dx_over_dt Jul 26 '20 at 02:03
  • Yes, there is always a global `this`, and the functions you mention are all ways to _force_ JS to set up a custom `this` context. And none of that applies here, because clearly this code assumes a classed object, while using an object primitive. – Mike 'Pomax' Kamermans Jul 26 '20 at 16:58

3 Answers3

3

You are using arrow functions. The this variable does exist within regular objects, but arrow functions pull their this from whatever this is when they're declared (unless you bind them, which would be an odd thing to do).

Change your functions to functions and it should work fine.

module.exports = {
    GetRandomNum(Min,Max) {
        var Range = Max - Min;   
        var Rand = Math.random();   
        return(Min + Math.round(Rand * Range)); 
    },
    mathCalculationtion() {
        var firstPlace = this.GetRandomNum(1, 9);
        return firstPlace;
    }
}

Note: To use it this way, you will need to import the module and call the function with the . syntax.

// This will work
const myModule = require('./my-module');

console.log(myModule.mathCalculationtion());

// This will not work
const { mathCalculationtion } = require('./my-module');

console.log(mathCalculationtion());

This is because this within the function is whatever the x in x.myFunc() is. If you just call myFunc() directly, it has no idea which object to apply it to. If you want to get around this, either define your functions in your module separately and reference them by name in the module, then export each function, or you can use .bind().

dx_over_dt
  • 8,418
  • 13
  • 39
  • 65
1

Change this.GetRandomNum(1, 9) to module.exports.GetRandomNum(1, 9) or

declare your functions outside of the module.exports block:

    var getRandomNum = (Min,Max) => {
        var Range = Max - Min;   
        var Rand = Math.random();   
        return(Min + Math.round(Rand * Range)); 
    }
    var mathCalculationtion = () => {
        var firstPlace = getRandomNum(1, 9);
        return firstPlace;
    }

then:

    module.exports = {
        getRandomNum,
        mathCalculationtion
    }
White Link
  • 86
  • 7
0

Use module.exports instead of this:

module.exports = {
    GetRandomNum(Min,Max) {
        var Range = Max - Min;   
        var Rand = Math.random();   
        return(Min + Math.round(Rand * Range)); 
    },
    mathCalculationtion() {
        var firstPlace = module.exports.GetRandomNum(1, 9);
        return firstPlace;
    }
}

It works for me just fine in NodeJs v12.16.1.

Andrei
  • 357
  • 1
  • 6