2

I have been working with JS for a few months now and I stumbled upon this interesting (at least to me) thing.

Take a look at this code:

class myClass
{
    constructor()
    {
        this.x = 0;
    }
}

function myFunc(){}

myClass.myFunc = myFunc;

I can call myClass.myFunc(), but myClass is just a function. In fact, I could rewrite it as

function myClass()
{
    this.x = 0;
}

and it would behave the same and I would still be able to call myClass.myFunc(). So what actually is a function (like, "under the hood")? It seems to behave more like an object that can be called if it makes any sense, thus being able to have fields of its own.

Also, is this considered bad practice? In node I have

module.exports = myClass;
module.exports.myFunc = myFunc;

Is this okay to do? Or is this frowned upon? What are the cons, if any?

EDIT: I'm not asking how to have a static method, I'm asking why this happens.

3
  • 3
    Everything in Javascript is object. Commented Jul 20, 2019 at 17:15
  • @MaheerAli except primitive types. :P Commented Jul 20, 2019 at 17:33
  • @stealththeninja Actually they are also objects. Because Numbers, Strings and Booleans have properties and methods. Commented Jul 20, 2019 at 18:59

2 Answers 2

4

In JavaScript a function is an actual value. Values are categorised by data type (a data type describes a possible set of values). JavaScript has the following data types:

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

A function is obviously neither of the first 6, it is indeed an Object. And as such it can have arbitrary properties, just like any other object.

What makes a function object special?

Per specification objects have "internal methods". You can think of them as being just like normal properties except that they cannot be accessed in user code. Only the JavaScript engine can access them.

Function objects have an internal method called [[Call]] and an internal slot called [[ECMAScriptCode]]. The latter contains a parsed representation of the function body and is evaluated when [[Call]] is invoked (which happens in a call expression (foo())).

Specifically for classes, or rather the functions created through class syntax, there is also the internal [[Construct]] method. It works very similar to [[Call]] but is used when a function is invoked via the new keyword.

See also

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

Comments

2

You can use static method:

class myClass
{
    constructor()
    {
        this.x = 0;
    }
    static myFunc(){
        return 'Hello';
    }
}

module.exports = myClass

or simply export a new instance of myClass:

class myClass
{
    constructor()
    {
        this.x = 0;
    }
    myFunc(){
        return 'Hello';
    }
}

module.exports = new myClass

In both approaches you can treat myFunc as a static function:

const myclass = require('myClass');
myClass.myFunc();
// will print out 'Hello'

1 Comment

I guess this answers my question on whether or not it's good practice. If the static keyword exists (which I didn't know of, thanks!) then there should be no problem in doing it. However, I still want to know what are functions under the hood and how they work. Since your answer does not answer all of my questions I won't be marking it as the accepted answer.

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.