# JavaScript/ECMAscript 6 classes organization

I have been trying to wrap my head around all the new options in ECMAscript 6 and to do this I tried to develop a simple setup which would allow me to place absolutely positioned <div>s on the page.

main.js:

import {Screen} from './objects/screen';
import {Position} from './objects/position';

var welcomeScreen = new Screen("Hello World");
welcomeScreen.title = "Hello World2";
welcomeScreen.position = new Position(100,100);
//Make sure the following does work if you have any advices, because there is a simple mistake which breaks this:
console.log(welcomeScreen.position.x);

var secondScreen = new Screen("Second screen", new Position(200,200));


objects/baseobject.js:

export class BaseObject{
on(eventname,func){
if(typeof this.listeners == "undefined"){
this.listeners = {};
}
if(typeof this.listeners[eventname] == "undefined"){
this.listeners[eventname] = [];
}
this.listeners[eventname].push(func);
return this;
}
trigger(eventname){
if(this.listeners && this.listeners[eventname]){
for(let func of this.listeners[eventname]){
func.call(this);
}
}
}
}


objects/screen.js:

import {BaseObject} from './baseobject';
// private properties:
var pp = {
position: Symbol(),
title: Symbol()
};
export class Screen extends BaseObject{
constructor(title,position = new Position(0,0)){
this.element = document.createElement("div");
this.title = title;
this.position = position;
document.body.appendChild(this.element);
}
reposition(){
this.element.style.left = this.position.x + "px";
this.element.style.top = this.position.y + "px";
}
set position(position){
var that = this;
this[pp.position] = position;
this[pp.position].on("positionchange",function(){
that.reposition();
}).trigger("positionchange");
}
get position(){
return this[pp.position];
}
set title(value){
this[pp.title] = value;
this.element.textContent = value;
}
get title(){
return this[pp.title];
}
}


objects/position.js:

import {BaseObject} from './baseobject';
// private properties:
var pp = {
x: Symbol(),
y: Symbol()
};
export class Position extends BaseObject{
constructor(x,y){
this[pp.x]=x;
this[pp.y]=y;
}
set x(value){
this[pp.x]=x;
super.trigger("positionchange");
}
get x(){
return this[pp.x];
}
set y(value){
this[pp.y]=y;
super.trigger("positionchange");
}
get y(){
return this[pp.y];
}
}


You can transpile ES6 to ES3 (I think it is 3) using (Google) Traceur.

Points of interest:

• Are there nice ES6 language features I am forgetting?
• Is there a nicer way to handle the 'set triggers' (-> private property construction)?
• Should I be using modules? Combine classes into the same files? etc.
• Traceur does not support private in class bodies.. github.com/google/traceur-compiler/issues/57 That's a bit of a let down. Mar 5 '14 at 16:26
• Have been reading the spec now for the last half hour and for the life of me, I can't figure out how private properties are 'supposed' to work (regardless of Traceur). Mar 5 '14 at 18:38
• I looked at wiki.ecmascript.org/doku.php?id=harmony:classes#class_body -> check out the constructor. Mar 5 '14 at 18:55
• That one is old and superseded by wiki.ecmascript.org/… Mar 5 '14 at 19:01
• And yeah, I would have loved it if they could have agreed on that one. I thought you were talking about the new Name() stuff which I can't figure out. Mar 5 '14 at 19:02

Most interesting,

• In BaseObject, you should really have a constructor that builds this.listeners, it would make your code much cleaner afterwards
• I am not sure why your listeners are not private in BaseObject ?
• I am not sure what is more important to you, learn EC6 or position divs efficiently, if the latter is more important, than this code is massive overkill ;)

If you want to avoid having a constructor for BaseObject, then I would re-write on like this:

on(eventname,func){
this.listeners = this.listeners || [];
this.listeners[eventname] = this.listeners[eventname] || [];
this.listeners[eventname].push(func);
return this;
}

• To point 1 I did this because this way a user doesn't need to call the super constructor on each and every object he constructs. To point 2, you are absolutely right, I forgot entirely. And lastly to point 3: It is to learn EC6 whilst making a mobile app framework slowly (this was just me trying to figure out the setup). Mar 5 '14 at 18:29
• Great suggestion btw@on :D Mar 5 '14 at 19:44

So, going to 'answer' my own question here with a nice thing I discovered since then. Might expand my answer if I discover more stuff.

In ECMAscript 6 rather than

var that = this;
something.on("positionchange",function(){
that.reposition();
});


You can do

something.on("positionchange",() => {
this.reposition();
});


As the this scope doesn't change.

• It's exciting though? Already with the latest additions I have stopped using typical javascript libraries for most my projects and with ES6 I can get rid of a couple I occasionally use again :D Mar 6 '14 at 23:15