`this` one weird trick

What's `this`

`this` is a "free" contextual reference that every function gets. 

 

What it references depends on how the function is invoked.

There are three contexts for `this`

  • Functions
  • Constructors
  • Methods

`this` in a function

When used in a regular function call, `this` refers to the global object (window).

`this` in a Constructor

When used in a constructor, `this` refers to the newly created object.

`this` in a Constructor

It's just an ordinary object, so you can add what ever you like to it.

`this` in a Constructor

You don't even need the `return` statement.

`this` in a Constructor

In fact, the `return` statement is ignored.

`this` in a Constructor

Unless you return an object.

No, it's not just you, it's weird.

Solving for the "Oops" Effect

Oops! I forgot to invoke that constructor with `new`

- Everyone at some point

Even better. Don't use `new`

It is never a good idea to put new directly in front of function

-Douglas Crockford (http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/)

WARNING: Highly Controversial!
Opinions may vary... but they're wrong.

`this` in a method

When used in a method on an object, `this` refers to the host object (the thing that comes before the dot).

Gotchas

  1. Unless handled, failure to add a `new` to your constructor results in a borked object and polluted global.
     
  2. Constructors are just "newed" up functions in JS. It's not necessarily clear in the code what is a constructor and what is a function.
     
  3. Return statements are ignored in Constructors*.
     
  4. *Except when they're not. `this` is ignored if you return an object.

The Good News

  1. Use the factory pattern to create new object that don't use `this`.
  2. Use `Object.create` and family to create computed properties.
    bonus: you get a more consistent api for your object. (Access and assign all the things !)
     
  3. Exercise your functional purity.
  4. You're welcome.

`this` is almost entirely unnecessary.

I got your calculated values right here

var o = (function () {
    
    var firstName = "Cory",
        lastName = "Brown";

    return Object.create(null, {
        firstName: {
            get: () => firstName,
            set: (fn) => firstName = fn
        },

        lastName: {
            get: () => lastName,
            set: (ln) => lastName = ln
        },
        
        fullName: {
            get: () => firstName + ' ' + lastName
        }
    });

})();

I got your calculated values right here

var o = (function () {
    
    var firstName = "Cory",
        lastName = "Brown";

    return Object.create(null, {
        firstName: {
            get: () => firstName,
            set: (fn) => firstName = fn
        },

        lastName: {
            get: () => lastName,
            set: (ln) => lastName = ln
        },
        
        fullName: {
            get: () => firstName + ' ' + lastName
        }
    });

})();