JavaScript: The Fun Parts
Tags: javascript, webdev, programming, fun
Published: 2019-02-12 17:21:52

---
title: JavaScript: The Fun Parts
published: true
description: An editable collection of rarely used JavaScript features. The goal is to make you play with occasional horror on your face.
tags: javascript, webdev, programming, fun
cover_image: https://thepracticaldev.s3.amazonaws.com/i/2ip75aytxnytb6m5mxti.jpg
---

JavaScript is evolving rapidly with a bunch of yearly additions. Some of them never reach the spotlight, others get forgotten or deprecated. Let's put these into increasingly hacky editable code sandboxes. The goal is to make you play with occasional horror on your face.

> The examples are taken from real libraries or apps that I have written over the years. The last few are controversial though, and I do not encourage you to use them in your code.

## Finally

I usually use [finally](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch#The_finally_clause) when I have to wrap other devs' functions with some extra logic. `finally` does this without messing with the original behavior - like return values or thrown Errors.

This example instruments the passed function with performance measurements.

```js
function measure (fn) {
  const start = Date.now()
  try {
    return fn()
  } finally {
    console.log(`${fn.name} took ${Date.now() - start} ms`)
  }
}
```

[![Edit l9wj5zx20l](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/l9wj5zx20l?module=%2Fsrc%2Fmeasure.js)

## WeakSet and WeakMap

[These two](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) provide truly private properties (unlike [Symbols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)). I use them when I have to append some metadata to others' objects. Directly mutating these would be bad manners, plus you get screwed if the object is [frozen](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze).

This example stringifies the passed object and caches the result. The memoization speeds up the operation and the WeakMap usage avoids object pollution and memory leaks.

```js
const cache = new WeakMap()

export default function stringify(obj) {
  let result = cache.get(obj)
  if (!result) {
    result = JSON.stringify(obj, null, 2)
    cache.set(obj, result)
  }
  return result
}
```

[![Edit wn1ror8jz5](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/wn1ror8jz5?module=%2Fsrc%2Fstringify.js)

## Proxy

[Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) can tweak language behavior. Most of the time I use them to *extend* the language and occasionally I use them completely change some default behavior.

This reactive example lets you create observables and reactions. A reaction automatically re-runs when an observable - used inside it - is mutated. The snippet is extremely oversimplified but some additional coding can take it pretty far.

```js
let runningFn
const reactions = new WeakMap()

export function observe(fn) {
  runningFn = fn
  try {
    return fn()
  } finally {
    runningFn = undefined
  }
}

export function observable(obj) {
  return new Proxy(obj, {
    get(target, key, receiver) {
      runningFn && reactions.set(target, runningFn)
      return Reflect.get(target, key, receiver)
    },
    set(target, key, value, receiver) {
      Reflect.set(target, key, value, receiver)
      const reaction = reactions.get(target)
      reaction && reaction()
    }
  })
}
```

[![Edit wn7nz5x7x8](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/wn7nz5x7x8?module=%2Fsrc%2Fobserver.js)

## New Function

[new Function()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) is similar to `eval` but it creates functions in the global scope, which is outside of any `'strict mode'` declarations. We will abuse this fact soon.

This example gets the `global` object - regardless of the platform - which is currently trickier than it should be. It is also used in the [ES2019 globalThis proposal](https://github.com/tc39/proposal-global) polyfill.

```js
const globalThis = new Function('return this')()
```

> This won't work if you have [CSP](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) set up for your page.

## With

[with](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) extends the scope chain for a statement. Sadly, it is deprecated and it won't work in strict mode - which includes ES6 modules. A few tricks can save the day though.

This example lets you write Vue or Angular like template files and renders them in the context of the passed state.

```js
export default function compile(template) {
  return new Function("state", `with (wrap(state)) { return \`${template}\` }`)
}

window.wrap = state => new Proxy(state, {
  has: () => true
})
```

[![Edit wyv631ry7k](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/wyv631ry7k?module=%2Fsrc%2Fcompiler.js)

It tweaks `with` behavior with the following tricks:

- It uses `new Function()` - instead of `eval` - to create functions in the global scope. The global scope is outside strict mode so `with` works there.

- It uses Proxies to tweak `with` behavior a bit. Normally `with` extends the scope chain and does not replace it completely. When a property is not found on the passed object it will search for it in the next scope - in our case the global one. We do not want the global scope to leak into the template so we have to trick `with` into thinking that every possible property is present on the passed object. This is pretty simple with the [`has` Proxy trap](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/has).

## Everything Together

We accidentally created a blazing fast lightweight MVC framework along the way.

{% codesandbox 72oynq44jq %}

Please [check the repo here](https://everythingexcelblog.files.wordpress.com/2016/09/rolled.png?w=656) and don't forget to leave a star!

---

*I hope you found some time to play with the sandboxes. Leave a comment if you created something crazy.*

*Thanks for reading!*