Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

223
Views
Too much recursion error when a classfield is not declared

If we declare a class like this:

class client{
  constructor(name){
    this.name = name
  }

  get name()
  {
    return this.name ; 
  }
  set name(val)
  {
    this.name = val ;
  }
}

Instantiate it will give an error ( too much recursion) and that normal because the setter will call itself.

class client{
  constructor(name){
    this.name = name
  }

  get name()
  {
    return this.name ; 
  }
  set name(val)
  {
    this.name = val ;
  }
}

let cl = new client(); 

But when i declare 'name' as class field i don't get that error, I don't understand why.

class client{
  name = null ; 

  constructor(name){
    this.name = name
  }

  get name()
  {
    return this.name ; 
  }
  set name(val)
  {
    this.name = val ;
  }
}

let p = new client(); 
console.log(p) ;

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

TL;DR You can't have both a data property and an accessor property with the same name on the same object, and if you have a data property on an object, any property with the same name on its prototype won't be used (unless you do so explicitly). The name class field definition creates an own data property on the object being constructed.


In the first case (as I think you know), this.name inside the name setter calls the name setter again, recursing until you run out of stack. (And the same for the getter, if you used it.)

So what's different when you have that name field definition there?

The way class fields are defined, that name definition creates an own property on the instance being created, as though you had this code at the beginning of the constructor (just after a super call if this were a subclass):

constructor(name) {
    // Definition of `name` field:
    Object.defineProperty(this, "name", {
        value: undefined,
        writable: true,
        configurable: true,
        enumerable: true,
    });
    // Remainder of constructor code:
    this.name = name;
}

Since it's an own property, this.name resolves to that data property, not to the accessor property on the prototype that the get name and set name accessor definitions create. So those accessors on p's prototype are never used.

You can see that if you look at the definition of the property in your second example:

class client {
  name = null; 

  constructor(name){
    this.name = name;
  }

  get name()
  {
    return this.name ; 
  }
  set name(val)
  {
    this.name = val ;
  }
}

let p = new client(); 
console.log(p) ;
console.log(Object.getOwnPropertyDescriptor(p, "name"));

If you want to have the accessor property, you could use a private field, which is quite new but supported in modern environments:

class Client {
    #name = null; 
  
    constructor(name) {
        this.#name = name;
    }
  
    get name() {
        return this.#name; 
    }

    set name(val) {
        this.#name = val;
    }
}

let p = new Client("Joe"); 
console.log(p.name);
console.log(Object.getOwnPropertyDescriptor(p, "name")); // undefined
console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(p), "name")); // accessor
.as-console-wrapper {
    max-height: 100% !important;
}

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!