0

I have a property in my LWC component.

I want to delete the value from it, so it becomes undefined.

In usual JS, I can just execute an statement

delete this.property

It is executed successfully, but the property keeps its previous value and is not changed to undefined.

However, this doesn't work in LWC code. Why?

2 Answers 2

1

For a class that extends LightningElement, the properties are intentionally locked down due to a design decision to improve performance. If you check the property, you will see that it does not exist as a property:

console.log(this.hasOwnProperty('property')); // false

This is because the properties have been converted to a getter/setter pair.

Normal classes don't have this problem:

class Sample {
  property = 'Hello World';
}

...

connectedCallback() {
  const sample = new Sample();
  delete sample.property;
  console.log(sample.property); // undefined
}

The fact that it behaves this way makes it very apparent that this is an intentional design choice and not a bug. I've written up a corresponding demo that highlights the difference between component classes and other classes.

Demo.

Edit:

This has been confirmed by the LWR team:

I suspect it could be because that all properties are now reactive by default, making the former decoration unnecessary for primitives.

You are right this is related to reactivity. To track class fields mutation, the LWC engine attaches a set of getter / setter. This observation is applicable to all the class fields (standard, tracked, and public).

Let's take the following example where CustomCmp with a single foo class property.

export default class CustomCmp extends LightningElement {
 foo = '';
}

The CustomCmp component would be interpreted at runtime as:

export default class CustomCmp extends LightningElement {
  _foo = '';
  
  get foo() { 
    // Some mutation tracking logic [...]
    return this._foo; 
  }
  set foo(value) { 
    // Some mutation tracking logic [...]
    this._foo = value; 
  }
}

The class field mutation tracking logic can be found here.

It's important to call out that the LWC engine does some internal manipulation to the component class, which might be surprising to experienced JavaScript developers. According to the JavaScript specification, class fields should be assigned to the class instance itself. This isn't the case for LWC components, where class fields are applied to the prototype.

This is the reason why in @nolanlawson's previous example, Object.hasOwn(this, 'foo') returns false on the first invocation (prior to deleting the property). This is a performance optimization, that we decided to add early on in LWC's development, to avoid the runtime overhead of re-creating those getters and setters on every component instance. That said it is something that we will likely change for LWC to adopt the latest JavaScript decorator proposal.

3
  • 1
    is this design decision documented anywhere? I won't agree that this WAD until I see some evidences; it looks pretty weird design decision IMHO
    – Patlatus
    Commented Feb 17, 2023 at 17:10
  • @Patlatus Fair enough. I've raised an issue about it, just to doublecheck. I'll update you when I get more info.
    – sfdcfox
    Commented Feb 18, 2023 at 0:26
  • @Patlatus No doc link, but a confirmation from someone who definitely would know what's going on. This is a design decision. See my edit.
    – sfdcfox
    Commented Feb 21, 2023 at 17:26
0

LWC is buggy and slow.

We need to use workaround like

this.property = undefined;

to delete the value from a property.

1
  • I wrote up a more complete answer after doing some research. This appears to be a design feature, not a flaw. Note that you aren't really deleting the property from the component, as it still literally exists, you've just set it to undefined. That's not the same as deleting the property itself. As a metaphor, that's the difference breaking your phone (the number for your phone still exists, but you can't be reached) and terminating your service (your number is now deactivated, even if you still have your phone).
    – sfdcfox
    Commented Feb 17, 2023 at 13:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .