How to create an object (with fields and methods) without defining a class?
let alice = {

    /** Field definitions. */
    firstName: "Alice",
    lastName: "Jones",
    birthYear: "1995",

    /**
     * Normal method.
     */
    greet: function() {
        return `Hello, I'm ${this.firstName}. How are you?`;
    }

};
How to define (and instantiate) a class with fields and a constructor?
class Person {

    // field definition
    firstName;

    /** 
     * Special constructor function (invoked by "new").
     */
    constructor(firstName) {
        this.firstName = firstName;
    }

}

let alice = new Person("Alice");
How to define a function inside a class (and invoke it)?
class Person {

    firstName;

    constructor(firstName) {
        this.firstName = firstName;
    }

    /**
     * Normal method (without "function" keyword).
     */
    greet() {
        return `Hello, I'm ${this.firstName}. How are you?`;
    }    

}

let alice = new Person("Alice");
console.log(alice.greet());
How to define a static function inside a class (and invoke it)?
class Person {

    static greetUnspecific() {
        return "Hello, I'm a person. How are you?";
    }

}

console.log(Person.greetUnspecific());
How to access the fields of the previously created Person object?
let alice = new Person("Alice");

// set:
alice.firstName = "Jane";

// get:
console.log(alice.firstName);

/* output:
Jane
*/
How to eliminate explicit field definitions?
class Person {

    // no explicit field definitions

    constructor(firstName) {
        // creates the field implicitly
        this.firstName = firstName;
    }

}

let alice = new Person("Alice");
console.log(alice.firstName);

/* output:
Alice
*/
How to define a getter?
class Person {

    // no explicit field definitions

    constructor(firstName) {
        // the property has been prefixed with an underscore
        // to prevent collision with the getter function
        this._firstName = firstName;
    }

    /** 
     * Getter for dynamically computing a property.
     */
    get firstName() {
        return this._firstName;
    }

}

let alice = new Person("Alice");
console.log(alice.firstName);
Is it possible to set the Person's first name in the previous example?
// the following invocation does not work (in strict mode), 
// because there is only a getter, but no setter:
alice.firstName = "Jane";

// however, the first name can still be changed by 
// directly writing to the the underscore property:
alice._firstName = "Jane";
console.log(`Alice's name is now ${alice.firstName}`);

/* output:
Alice's name is now Jane
*/
How to define a setter?
class Person {

    // no explicit field definition

    constructor(firstName) {
        // the property has been prefixed with an underscore
        // to prevent collision with the getter / setter function
        this._firstName = firstName;
    }

    get firstName() {
        return this._firstName;
    }

    /** 
     * Setter for performing value changes.
     */
    set firstName(firstName) {
        // validations / adaptations can be performed here
        console.log("inside setter!");
        this._firstName = firstName;
    }

}

let alice = new Person("Alice");
console.log(alice.firstName);

// the following invocation triggers the setter function:
alice.firstName = "Jane";
console.log(alice.firstName);

/* output:
Alice
inside setter!
Jane
*/