JSlang.dev

JavaScript Deep Dives with Wolfram. Since 2015
Inclusive, Test-Driven, Spec-Focused, Collaborative.

May 23, 2024
TestsSource
#72 `this`

Source Code

The source code we wrote during the event.

const assert = require('assert');

const outerThis = this;

describe('`function() {}` vs. `() => {}`', () => {
  
  it('`this` in a regular function is `undefined`', () => {
    'use strict'
    let theValueOfThis = 'defined';
    function fn() {
      theValueOfThis = this
    }
    fn();
    assert.equal(theValueOfThis, undefined);
  });
  it('`this` of a function instance is an instance of that function', () => {
    'use strict'
    let theValueOfThis = 'before';
    function fn() {
      theValueOfThis = this;
    }
    new fn();
    assert.equal(theValueOfThis instanceof fn, true);
    assert.equal(typeof theValueOfThis, 'object');
  });

  it('`this` in non-strict mode inside a function is the global scope', () => {
    let theValueOfThis = 'defined';
    function fn() {
      theValueOfThis = this
    }
    fn();
    assert.equal(theValueOfThis, global);
  });
  it('`this` inside a chain of arrow functions refers to the inner most `this` outside of the chain', () => {
    // Just try to modify the arrow function passed to `it` to be a regular function.
    let theValueOfThis = 'defined';
    const fn = () => {
      theValueOfThis = this
    }
    fn();
    assert.equal(theValueOfThis, outerThis);
  });
  it('`this` inside an arrow function, refers to the closest `this` defined', function() {
    // by using `function() {}` mocha, our test runner, create a `this` inside our test.
    const theTestsThis = this;
    let theValueOfThis = 'defined';
    const fn = () => {
      theValueOfThis = this
    }
    fn();
    assert.equal(theValueOfThis, theTestsThis);
  });
  
});

describe('`this.this`???', () => {
  it('an object can have a key called `this`', () => {
    const obj = {
      this: 42
    }
    assert.equal(obj.this, 42);
  });
  it('using `this.this` inside an object is possible', () => {
    const obj = {
      this: 42,
      getThis: function() {
        return this.this;
      }
    }
    assert.equal(obj.getThis(), 42);
  });
  it('using an arrow function to refer to `this` inside an object returns its closest this', () => {
    const theTestsThis = this;
    const obj = {
      getArrowThis: () => this,
    }
    assert.equal(obj.getArrowThis(), theTestsThis);
  });
});