11

Suppose I have the following code:

class Foo {
    constructor() {
        this.a = 1;
        this.b = 'something';
    }

    someMethod() {
        // Is this legal?
        let { a, b } = this;
    }
}

Is the destructuring assignment in someMethod legal?

My gut feeling is that it is fine, but I have seen no reference to this usage in any docs. It currently works in Babel, but presumably because under the hood Babel is transpiling the class into a function. My understanding is that (almost) everything in JS prototypically inherits from Object, so I might expect this to be true for Classes and Class instances too.

The only reference I've seen to what happens under the hood is here and specifies that the JS engine calls the internal method ToObject which will only throw a TypeError when it encounters null or undefined. But the ToObject docs don't explicitly mention class instances.

baseten
  • 1,362
  • 1
  • 13
  • 34
  • unrelated to your question, but do you any particular reason you used let instead of var? – Vlad Nicula Feb 22 '16 at 11:27
  • yes it is, but `()` after `Foo` isn't – Jaromanda X Feb 22 '16 at 11:46
  • 2
    many coders will just use `let` every time because they heard it was a good idea; regardless of whether any blocks are in-play or not... you gotta problem wit `let`? – dandavis Feb 22 '16 at 11:47
  • 1
    @VladNicula seems like an odd question for a minimal (almost) working example that is clearly designed to show the principal of what the question is about – Jaromanda X Feb 22 '16 at 11:48
  • @VladNicula - any reason not to? – nnnnnn Feb 22 '16 at 11:50
  • keep in mind that making a new object will bust your inheritance on an other-wise identical object... – dandavis Feb 22 '16 at 11:51
  • @JaromandaX - Yes you're right, typo - fixed – baseten Feb 22 '16 at 12:00
  • @VladNicula - as per the comment from @dandavis we've chosen to avoid using `var` altogether on this project and have this set up in the eslint rules. Didn't specifically mean to write it here, just in the habit now I guess. – baseten Feb 22 '16 at 12:08
  • @dandavis can you clarify what you mean about breaking inheritance? – baseten Feb 22 '16 at 12:11
  • i mean that even though `JSON.stringify()` on both will be `{"a":1,"b":"something"}`, one will inherit prototype methods and one will not. you probably knew that; i'm just clarifying for the kids out there... – dandavis Feb 22 '16 at 12:16
  • 2
    @all, I was just curios if there's a perf benefit of sorts. It's interesting how most of you got a negative vibe from my question :) – Vlad Nicula Feb 22 '16 at 13:07
  • @dandavis on both? `let { a, b } = this;` is a destructuring assigment, so produces two block scoped variables `a` and `b` with their values copied from `this` not another object, or am I missing something? :) – baseten Feb 22 '16 at 13:59
  • yeah, i was up too late and gotta mixed up. i do think the syntax can be less readable than repeating keys... – dandavis Feb 22 '16 at 20:58

1 Answers1

9

Destructuring objects is explicitly allowed and is a feature.
this merely refers to an object. There's nothing special about it.
As long as this refers to an object, this is absolutely fine. *

* this may not refer to an object depending on how you call someMethod, e.g. Foo.someMethod.apply(null). But then you really have bigger problems anyway.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • sure thanks, just wanted explicit clarification really as other examples only deal with plain objects not class instances – baseten Feb 22 '16 at 12:03
  • 1
    @baseten Your curiosity is understandable. :) Broadly speaking, the `class` syntax is a sugar over the existing ES5 approach of using function constructors with only a few semantic differences, so you end up with essentially the same thing: an object with properties you can access and destructure. (Main differences are minor, things like that classes must be invoked using the `new` keyword, class declarations aren't hoisted, prototype properties aren't enumerable, subclassing works a bit differently etc.) – Jordan Gray Feb 22 '16 at 13:56