# Replacement for \`this\` in cells?

**URL:** <https://talk.observablehq.com/t/replacement-for-this-in-cells/10897>\
**Category:** Help\
**Created:** [September 30, 2026, 4:50am UTC](https://talk.observablehq.com/t/replacement-for-this-in-cells/10897 "2026-09-30T04:50:24Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![akrawitz](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/akrawitz/32/4375_2.png) [@akrawitz](https://talk.observablehq.com/u/akrawitz)\
**Post date:** [September 30, 2026, 4:50am UTC](https://talk.observablehq.com/t/replacement-for-this-in-cells/10897/1 "2026-09-30T04:50:24Z")

</div>

In Observable Javascript, `this` refers to the previous state of a cell. This is very handy, because `this` can store the state of a simulation (both the visible state in DOM nodes and hidden data as well), and each time the cell is executed the simulation can advance by one time step. This made it easy to update only those parts of the simulation that changed while leaving everything else alone.

Here is the base of how I was using it:

[https://observablehq.com/@akrawitz/simulation-controls](https://observablehq.com/@akrawitz/simulation-controls)

I was, of course, building on the shoulders of giants, as shown here:

[https://observablehq.com/@mbostock/pause-a-generator](https://observablehq.com/@mbostock/pause-a-generator)

And here:

[https://observablehq.com/@tmcw/untitled/5](https://observablehq.com/@tmcw/untitled/5)

As far as I can tell, `this` doesn’t work the same way in new plain JavaScript/TypeScript cells. What would be the canonical replacement?

---

<div class="post-metadata">

**Author:** ![mbostock](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mbostock/32/9_2.png) [@mbostock](https://talk.observablehq.com/u/mbostock)\
**Post date:** [September 30, 2026, 2:15pm UTC](https://talk.observablehq.com/t/replacement-for-this-in-cells/10897/2 "2026-09-30T14:15:42Z")

</div>

The closest analogy is probably `Mutable`, and that reminds me I need to write some more documentation… you can see [the Framework docs on mutables](https://observablehq.github.io/framework/reactivity#mutables) for now.

The behavior of `this` in Observable JavaScript is another form of mutable state, and I think `Mutable` is an improvement over this because it makes it more explicit and more flexible. You can also think of `Mutable` as similar to React’s `useState` hook.

Adapting one of your simulation control examples, I’d first define the simulation state as a mutable, and then provide a getter (for peeking “non-reactively” at the state) and likewise a setter. The setter is important because it allows another cell (a cell other than the one that declared the mutable) to mutate the state.

```auto
const state = Mutable({cycle: 0});
const getState = () => state.value;
const setState = (s) => (state.value = s);
const epochLength = 20;

```

Then your simulation code can run in another cell:

```auto
{
  conSkip;
  let state = getState();
  if (conSkip.reset) {
    state = setState({cycle: 0});
  } else {
    state = setState({cycle: state.cycle + 1});
    if (conSkip.skip && (state.cycle % epochLength) === 0) {
      conSkip.stopSkip();
    }
  }
}

```

Notebook: [https://observablehq.com/d/1b4a0e1ad4bdc170](https://observablehq.com/d/1b4a0e1ad4bdc170)

---

<div class="post-metadata">

**Author:** ![mbostock](https://yyz2.discourse-cdn.com/flex030/user_avatar/talk.observablehq.com/mbostock/32/9_2.png) [@mbostock](https://talk.observablehq.com/u/mbostock)\
**Post date:** [September 30, 2026, 3:05pm UTC](https://talk.observablehq.com/t/replacement-for-this-in-cells/10897/3 "2026-09-30T15:05:49Z")

</div>

Another approach you could consider is using event listeners rather than reactive references (“reactions” to the input) to update your simulation state. That’s potentially a little simpler since you can use a single cell to define the simulation state and how it updates, rather than needing two cells.

To do this, you first `display` your input instead of using `view` (or do both, but you need to be able to reference the input in order to call `addEventListener`):

```auto
const conSkipInput = display(controls({skip: true, speed: 75}));

```

Then here’s your simulation `state` definition:

```auto
const state = Mutable({cycle: 0});
const epochLength = 20;

conSkipInput.addEventListener("input", (event) => {
  const conSkip = event.currentTarget.value;
  if (conSkip.reset) {
    state.value = {cycle: 0};
  } else {
    state.value = {cycle: state.value.cycle + 1};
    if (conSkip.skip && (state.value.cycle % epochLength) === 0) {
      conSkip.stopSkip();
    }
  }
});

```

(Note that this leaks an event listener if you re-run the state cell, so be careful when editing. If you want to clean that up, you can either use the `invalidation` promise to remove the event listener, or assign to `conSkipInput.oninput` instead of using `conSkipInput.addEventListener`.)

Notebook: [https://observablehq.com/d/f3c1b2d06555fc77](https://observablehq.com/d/f3c1b2d06555fc77)
