0

The question is how to refer to other static methods from a static method of a class exported from NodeJS module? Here's a setup. I have following modules: test1.js

var Parent = class  {
    static smethod1 () {
        return this.smethod2();
    }

    static smethod2 () {
        return "Testing tube";
    }
}

module.exports = {
    Parent:Parent
}

Then I have test2.js that requires this module

var mod = require('./test1');
var Parent = mod.Parent;

module.exports = {
    sm1: Parent.smethod1,
    sm2: Parent.smethod2
}

Finally, I have a code that is being run in run.js

var test2 = require('./test2');

console.log(test2.sm1());

Naturally, I want to see "Testing tube" line printed out. I am getting error

        return this.smethod2();
                    ^

TypeError: this.smethod2 is not a function 

Of course, there's shenanigans on NodeJS where this refers to a module, but shouldn't it be referring to a function instead ? Is there way to refer to static method smethod2 from smethod1 with current setup ? If not, what are the workarounds ?

4
  • You can have a look on this answer : stackoverflow.com/a/28979516/1681972 Commented Feb 28, 2017 at 4:16
  • If you have a class with only static methods, this is a sign that you should just exports the functions directly and delete the class, FYI. Commented Feb 28, 2017 at 4:20
  • @loganfsmyth This is simplification of course. Commented Feb 28, 2017 at 4:31
  • @Ravi, nope. babel-isation didn't seem to solve the problem. Commented Feb 28, 2017 at 4:42

1 Answer 1

2

The this keyword is kind of weird in JavaScript, and doesn't always refer to your instance like in most class based languages. In your case, when you call test2.sm1(), this is set to the test2 object, which is

{
    sm1: Parent.smethod1,
    sm2: Parent.smethod2
}

That object does not have a smethod2 function.

this gets set based on how a function is called in JavaScript, specifically with whatever is before the '.': ->test2<-.sm1().

There are several workarounds. First, after defining the Parent class, you could bind this for that function to the class:

var Parent = class  {
    static smethod1 () {
        return this.smethod2();
    }

    static smethod2 () {
        return "Testing tube";
    }
}

// bind `this` to `Parent`
Parent.smethod1 = Parent.smethod1.bind(Parent);

module.exports = {
    Parent:Parent
}

Alternatively, you could pass Parent as an argument to call or apply, which sets this manually for just that one invocation:

var Parent = require('./test1');
var test2 = require('./test2');

// call `test2.sm1` with a context of `Parent`    
console.log(test2.sm1().call(Parent));
Sign up to request clarification or add additional context in comments.

3 Comments

@EvgeniySharapov Interesting, I guess it does make sense in JavaScript that you can call other static methods with this. I've changed my answer.
Looks like using bind works ok. I have module.exports = { sm1: Parent.smethod1.bind(Parent), sm2: Parent.smethod2.bind(Parent) } in test2.js

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.