user13671197
user13671197

Reputation: 31

Call a getter function with its name in JavaScript?

When I create a class in JavaScript like this one:

class Person {
    _firstName = "";
    _lastName = "";

    constructor(firstName, lastName) {
        this._firstName = firstName;
        this._lastName = lastName;
    }

    get firstName() {
        return this._firstName;
    }

    get lastName() {
        return this._lastName;
    }

    fullName() {
        return `${this.firstName} ${this.lastName}`;
    }

}

let me = new Person("John", "Doe");

It creates a variable me that is an instance of Person. Its prototype has some functions whose names are “fullName” and “get firstName” (plus other functions)

I can call the function fullName by its name using:

me[“fullName”]();

John Doe

However, calling the getter function by its name throws an error:

me[“get firstName”]();

Uncaught TypeError: me.get firstName is not a function

Why does this behavior happen?

EDIT: Thanks for the replies. I know I can and should access it as a property. But I'd like to understand why accessing it by its name with the brackets notation does not work. Does that mean JavaScript has different kinds of functions since a behavior that works for one function does not work for another function (when it has a space in its name / is a getter or setter)?

Upvotes: 2

Views: 492

Answers (3)

trincot
trincot

Reputation: 351183

When a function is assigned to a variable or as a property value (maybe a getter), there are two names involved:

  • The name of the function
  • The name of the variable/property

These names are different entities and don't necessarily have to be the same.

Here is a simple object with property "a" that has as value a function whose name is "b":

let obj = {
    a: function b() { }
};

console.log("property: ", Object.keys(obj)[0]); // "a"
console.log("function: ", obj.a.name); // "b"

Now when the function does not get an explicit name, it is given one:

let obj = {
    a() { }
};

console.log("property: ", Object.keys(obj)[0]); // "a"
console.log("function: ", obj.a.name); // "a"

This may give the false impression that both names are one and the same string, but this cannot be true as the same function object might be assigned to different properties:

let obj = {
    a() { }
};
obj.c = obj.a;

console.log("property: ", Object.keys(obj)[1]); // "c"
console.log("function: ", obj.c.name); // "a"

Getters

The situation with a getter can be confusing, because the expression obj.a.name will not retrieve the name of the function, but will invoke the getter and then try to access the name property of the returned value.

To still get the name of the getter function, you can use Object.getOwnPropertyDescriptor as follows:

let obj = {
    get a() { }
};

console.log("property: ", Object.keys(obj)[0]); // "a"
console.log("function: ", Object.getOwnPropertyDescriptor(obj, "a").get.name); // "get a"

This is how a getter's function name is set by default. You can however set it explicitly to your desire using Object.defineProperty as follows:

let obj = {};
Object.defineProperty(obj, "a", { 
    get: function b() {},
    enumerable: true 
});

console.log("property: ", Object.keys(obj)[0]); // "a"
console.log("function: ", Object.getOwnPropertyDescriptor(obj, "a").get.name); // "b"

Conclusions

  • A property name does not necessarily match with the name of the function that might be the property's value.

  • A property is identified by property name, not by the name of the function that might be associated with it.

  • The function object, that serves as a getter property, can be accessed with Object.getOwnPropertyDescriptor(object, propertyName).get

Upvotes: 2

BitMaster48
BitMaster48

Reputation: 76

When doing this:

get firstName() {
    return this._firstName;
}

it´s defining a property and the you have to call it over:

me.firstName;

doing it like this:

getFirstName() {
    return this._firstName;
}

is really defining a getter function and you can call it like this:

me.getFirstName();

Maybe this is helpfull: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Functions/get

Upvotes: 0

Ricardo Rocha
Ricardo Rocha

Reputation: 16266

You should access it as a normal property like this:

me["firstName"];

But, if you know already the name, you could access the firstName value like this:

me.firstName

Typically, you use the first form if you want to access a property of an object using a variable like this:

const person = new Person("John", "Doe");
const propertyName = "firstName";
const firstName = person[propertyName];

If you want to know more about getter and setters check out this and this.

Follows a fully working example:

class Person {
    _firstName = "";
    _lastName = "";

    constructor(firstName, lastName) {
        this._firstName = firstName;
        this._lastName = lastName;
    }

    get firstName() {
        return this._firstName;
    }

    get lastName() {
        return this._lastName;
    }

    fullName() {
        return `${this.firstName} ${this.lastName}`;
    }

}

const me = new Person("John", "Doe");
const propertyName = "firstName";
console.log(me["firstName"])
console.log(me.firstName)
console.log(me[propertyName])

Upvotes: 1

Related Questions