Skip to content

Instantly share code, notes, and snippets.

@karol-majewski
Created September 8, 2020 16:38
Show Gist options
  • Save karol-majewski/94b0ada5501eed0796bcfabae9177446 to your computer and use it in GitHub Desktop.
Save karol-majewski/94b0ada5501eed0796bcfabae9177446 to your computer and use it in GitHub Desktop.
Property binding order in JavaScript classes (what TypeScript will not save you from)
class Foo {
options = {
ns: this.namespaces
};
constructor(namespaces = []) {
this.namespaces = namespaces;
}
}
console.log(
new Foo().namespaces, // []
new Foo().options.ns // undefined
)
@karol-majewski
Copy link
Author

karol-majewski commented Sep 8, 2020

When you do this in TypeScript:

class Foo {
    options = {
        ns: this.namespaces
    };

    constructor(public namespaces = []) {
      this.namespaces = namespaces;
    }
}

The generated JavaScript will look like this:

class Foo {
    constructor(namespaces = []) {
        this.namespaces = namespaces;
        this.options = {
            ns: this.namespaces
        };
        this.namespaces = namespaces;
    }
}

console.log(
    new Foo().namespaces, // []
    new Foo().options.ns // []
)

Which makes it work.

On the contrary, Babel does not pull property assignment into the constructor.

"use strict";

function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }

function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var Foo = function Foo() {
  var namespaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];

  _classCallCheck(this, Foo);

  _defineProperty(this, "options", {
    ns: this.namespaces
  });

  this.namespaces = namespaces;
  this.namespaces = namespaces;
};

console.log(new Foo().namespaces, // []
new Foo().options.ns // undefined
);

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