15
\$\begingroup\$

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.element.classList.add("screen");
        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.
\$\endgroup\$
11
  • \$\begingroup\$ Traceur does not support private in class bodies.. github.com/google/traceur-compiler/issues/57 That's a bit of a let down. \$\endgroup\$
    – konijn
    Commented Mar 5, 2014 at 16:26
  • \$\begingroup\$ 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). \$\endgroup\$ Commented Mar 5, 2014 at 18:38
  • \$\begingroup\$ I looked at wiki.ecmascript.org/doku.php?id=harmony:classes#class_body -> check out the constructor. \$\endgroup\$
    – konijn
    Commented Mar 5, 2014 at 18:55
  • \$\begingroup\$ That one is old and superseded by wiki.ecmascript.org/… \$\endgroup\$ Commented Mar 5, 2014 at 19:01
  • \$\begingroup\$ 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. \$\endgroup\$ Commented Mar 5, 2014 at 19:02

2 Answers 2

13
\$\begingroup\$

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;
}
\$\endgroup\$
2
  • \$\begingroup\$ 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). \$\endgroup\$ Commented Mar 5, 2014 at 18:29
  • \$\begingroup\$ Great suggestion btw@on :D \$\endgroup\$ Commented Mar 5, 2014 at 19:44
8
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Mar 6, 2014 at 23:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.