28

See how x and y are declared in constructor:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

is there an way to declare properties outside of functions for instance:

class Point {
  // Declare static class property here
  // a: 22
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }
  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

So I want to assign a to 22 but I am unsure if i can do it outside the constructor but still inside the class..

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Cisum Inas
  • 11,552
  • 11
  • 40
  • 55

2 Answers2

44

Initializing properties directly on a class in ES6 is not possible, only methods can currently be declared in this way. Same rules stand in ES7 as well.

However, it is a proposed feature that might come after ES7 (currently in stage 3). Here is the official proposal.

Additionally, the syntax the proposal is suggesting is slightly different (= instead of :):

class Point {
  // Declare class property
  a = 22
  // Declare class static property
  static b = 33
}

If you are using Babel, you can use the stage 3 settings to enable this feature.

Here's a Babel REPL example


The other way to do this in ES6, other than in the constructor, is to do it after the class definition:

class Point {
  // ...
}

// Declare class property
Point.prototype.a = 22;

// Declare class static property
Point.b = 33;

Here's a good SO Thread diving into this topic some more


Note:

As Bergi mentioned in the comments, the suggested syntax:

class Point {
  // Declare class property
  a = 22
}

is just syntactic sugar to provide a shortcut for this code:

class Point {
  constructor() {
    this.a = 22;
  }
}

Where both of those statements assign a property to an instance.

However, this isn't exactly the same as assigning to the prototype:

class Point {
  constructor() {
    this.a = 22;  // this becomes a property directly on the instance
  }
}

Point.prototype.b = 33; // this becomes a property on the prototype

Both would still be available via an instance:

var point = new Point();
p.a // 22
p.b // 33

But getting b would require going up the prototype chain while a is available directly on the object.

enter image description here

nem035
  • 34,790
  • 6
  • 87
  • 99
  • Couldn't you just use `static get x(){}` as well? Just wondering. In effect its the same thing right? – somethinghere Jul 08 '16 at 14:56
  • Well, it's not really the same effect but can be similar. You can use `get` to obtain a constant value or another value declared in the constructor which is not the same as declaring a value that can be directly get/set – nem035 Jul 08 '16 at 14:57
  • 1
    Hmmm true. Ah well, thank god its only syntactic sugar and we can always rely on js's great object legacy :) – somethinghere Jul 08 '16 at 15:00
  • 2
    Gotta love them prototypes :) – nem035 Jul 08 '16 at 15:03
  • You might want to add that `a = 22` is not the same as assigning to the prototype, instead it is very confusing sugar for creating instance properties in the constructor. – Bergi Jul 09 '16 at 11:20
1

@nem035 is right that it is in proposal stage.

However, @nem035's sugggetion is one way to achieve it as class instance member.

// Declare static class property here

Seems you are looking to declare a static member. If yes, JavaScript way is

class Point {
  // ...
}
Point.a = '22';

The way you are actually expecting can be done in TypeScript

class Point {
     static a = 22;
}

The compiled output will be same as above example

Point.a = '22';