Skip to content

Isn't section 5.1 "Use object destructuring" conflicting with 3.3 "Use object method shorthand" ? #3136

Open

Description

@ericmorand

In section 5.1 it is stated the following:

Use object destructuring when accessing and using multiple properties of an object.

In section 3.3, it is stated the following:

Use object method shorthand.

Let's look at the following example:

const foo = {
   bar: 5,
   // applying 3.3
   computeSomething() {
      return this.bar + 5;
   }
};

// applying 5.1
const {bar, computeSomething} = foo;

console.log(bar);

computeSomething();

The last instruction throws the following error:

TypeError: Cannot read properties of undefined (reading 'bar')

So, applying both 3.3 and 5.1 can lead to an incorrect code. Either we have to use arrow functions in objects definition; or we have to not use destructuring; but both 3.3 and 5.1 can't be recommended together without creating potential issues. At least, that's what I'm feeling.

What do you think? Did I miss the point or a clarification in the specs about that?

Activity

  1. ljharb commented on Jun 26, 2025

    @ljharb
    Collaborator

    The incorrect code is the code using this in "not a class".

  2. ericmorand commented on Jun 26, 2025

    @ericmorand
    Author

    Make sense. Does it mean that destructuring section does not apply to class instances ?

  3. ljharb commented on Jun 26, 2025

    @ljharb
    Collaborator

    Yep, exactly.

  4. ericmorand commented on Jun 27, 2025

    @ericmorand
    Author

    Can you explain the why ? Where do you draw the line between what is named Object in the documentation, and what you name Class instance? Aren't class instances objects?

    Also, if there is a rule about class instances saying that they must not be destructured, how do you recommend that we actually know that we are destructuring a class instance?

    Consider this:

    service.mjs

    export const service = new (class {
       foo = 5;
    
       doSomething() {
         return this.foo;
      }
    });

    index.mjs

    import {doSomething} from "./service.mjs";
    
    doSomething();

    How are developers expected to know that what is exported by service.mjs is a class instance, and thus must not be destructured?

  5. ljharb commented on Jun 27, 2025

    @ljharb
    Collaborator

    You always have to know what a thing you're importing is - without exception. Also, import { doSomething } is not destructuring, it's a named import, which is something quite different. Your example will throw.

  6. ericmorand commented on Jun 27, 2025

    @ericmorand
    Author

    Also, import { doSomething } is not destructuring, it's a named import, which is something quite different.

    My example was wrong, sorry.

    import {service} from "./service.mjs";
    
    const {doSomething} = service;
    
    doSomething();

    You always have to know what a thing you're importing is - without exception.

    So, we have to read the source code of everything that we import, this is the official AirBnb recommandations?

  7. ericmorand commented on Jun 27, 2025

    @ericmorand
    Author

    Also, I'm curious about what you mean by "You always have to know what a thing you're importing is".

    The what is the type, the interface, the shape of the thing. It is not its implementation: this would be the how.

    If I import something that is documented as of type Foo, I know what the thing is - a Foo.

    So, do you mean that we MUST know how a thing that we import is implemented?

  8. ljharb commented on Jun 27, 2025

    @ljharb
    Collaborator

    It's not just an airbnb recommendation - in all programming, everywhere, without exception, you have to know what you're importing. You can do that by reading docs, by reading the source code, or by playing around in a repl, but you still must know.

    If a function depends on its receiver in JavaScript, that's something you simply have to know "somehow", or you won't be able to use it properly.

  9. ericmorand commented on Jun 27, 2025

    @ericmorand
    Author

    in all programming, everywhere, without exception, you have to know what you're importing

    Yes, what. Not how.

    You can do that by reading docs, by reading the source code, or by playing around in a repl, but you still must know.

    The docs give the what. Now, I see that you recommend that we read the source code of every single library that we use, or play around with it on a repl. I think it is time for me to end this conversation then.

  10. ljharb commented on Jun 27, 2025

    @ljharb
    Collaborator

    That's not what I'm recommending - the docs would count too, and yes, that is how programming works - you can't use something if you don't have some expectation of what interface and semantics it has.

    How you import it is the same regardless of which method you use - const {doSomething} = service; is the problem, and that's not an import.

  11. Azimkhan01 commented on Aug 16, 2025

    @Azimkhan01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions