2

Okay, so according to my knowledge, we would write a class constructor like so

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    //anything outside of constructor belong to this.prototype

    getName() {
        console.log(this.name);
    }
    getAge() {
        console.log(this.age);
    }
}

So instead, if I write something like this:

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    getName() {
        console.log(this.name);
    }
}

User.prototype.getAge = function () {
    console.log(this.age);
};

It should technically be exactly the same, right? Or I am wrong? Because when I tried this which each one, I get 2 different result:

let user = new User('john', 23);

let properties = [];

for (let prop in user) {
    properties.push(prop);
}

console.log(properties); //The first code result : ["name", "age"]
                         //The second code result : ["name", "age", "getAge"]

So what is the difference between the two?

1
  • 1
    class defines the methods in it as non-enumerable, whereas assigning a new property directly to the prototype, creates an enumerable property (for..in iterates thorugh enumerable properties only). Commented Apr 28, 2020 at 10:16

3 Answers 3

1

The difference between the two is that using User.prototype.getAge = ... will add the property with the property descriptor enumerable: true. This means it shows up in for...in loops.

The for...in statement iterates over all enumerable properties of an object that are keyed by strings (ignoring ones keyed by Symbols), including inherited enumerable properties.

class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    getName() {
        console.log(this.name);
    }
}

User.prototype.getAge = function () {
    console.log(this.age);
};

let user = new User('john', 23);
let properties = [];

for (let prop in user) {
    properties.push(prop);
}

console.log(properties);

console.log(Object.getOwnPropertyDescriptor(User.prototype, "getName"));
console.log(Object.getOwnPropertyDescriptor(User.prototype, "getAge"));

If you want to define the prototype the exact same way you'll have to use the same property descriptor. This can be achieved with Object.defineProperty():

Object.defineProperty(User.prototype, "getAge", {
    value: function () {
        console.log(this.age);
    },
    writable: true,
    enumerable: false,
    configurable: true,
});
Sign up to request clarification or add additional context in comments.

Comments

0

The class syntax is only a sytactic sugar.

Comments

0

In the second case, you are adding a property called getAge. And its type is function.

Comments

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.