# Assigning a static method as an expression to a variable results in "this" as undefined. Why does the this context get lost??

**URL:** https://es.discourse.group/t/assigning-a-static-method-as-an-expression-to-a-variable-results-in-this-as-undefined-why-does-the-this-context-get-lost/953
**Category:** I have questions
**Created:** [August 29, 2021, 1:26pm UTC](https://es.discourse.group/t/assigning-a-static-method-as-an-expression-to-a-variable-results-in-this-as-undefined-why-does-the-this-context-get-lost/953 "2021-08-29T13:26:43Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![VIEWVIEWVIEW](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/viewviewview/32/986_2.png) [@VIEWVIEWVIEW](https://es.discourse.group/u/VIEWVIEWVIEW)
#### Post date: [August 29, 2021, 1:26pm UTC](https://es.discourse.group/t/assigning-a-static-method-as-an-expression-to-a-variable-results-in-this-as-undefined-why-does-the-this-context-get-lost/953/1 "2021-08-29T13:26:43Z")

</div>

A class itself is a function:

```javascript
class Foo {}
console.log(typeof Foo)
// function

```

Static methods are called on the class itself, instead of an instance of a class.

I declare a static method `b`, which returns another static method `a` from the same class. When I now assign the static method `b` as an expression to a variable like `const testB = Meme.b`, the `this`-context gets lost (undefined).

I do not understand why this happens. Can someone shine some light on why this is?

Here is a more elaborate example ([codepen](https://codepen.io/viewviewview/pen/YzQyJqK?editors=1111)):  
✅ = expected output  
❌ = unexpected output

```javascript
class Meme {
  static a() {
    return 1;
  }

  static b() {
    return this.a()
  }
}

// ---

/*
* works as expected
*/
console.log( Meme.a() ) // output: 1 ✅ 

const testA = Meme.a

testA() // output: 1 ✅ 

// ---

/*
* When binding Meme.b to a variable, the `this` context gets lost.
* Does _NOT_ work as expected
*/
console.log( Meme.b() ) // output: 1 ✅ 

const testB = Meme.b;

testB() // expected output: 1 ❌
// actual output: Uncaught TypeError: Cannot read property 'a' of undefined
// -- why is 'this' undefined? why does fn not bind to the Meme-context?

```

---

<div class="post-metadata">

### Author: ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)
#### Post date: [August 29, 2021, 2:25pm UTC](https://es.discourse.group/t/assigning-a-static-method-as-an-expression-to-a-variable-results-in-this-as-undefined-why-does-the-this-context-get-lost/953/2 "2021-08-29T14:25:36Z")

</div>

You're not using auto-binding functions (the arrow functions) - this means the functions do not store the "this" context at all.

The only reason `Meme.b()` works, is because Javascript automatically uses what's on the left-hand side of the "." as the "this" value whenever calling a function on the right-hand side. (Arrow functions will just ignore this provided "this" value and use the one they captured instead). As you can see, when you've plucked that function off and called it directly, you're not calling it from an object anymore (i.e. you're not using a "." when calling it), so Javascript has no idea what the "this" should be, so it sets it to undefined.

With these principles in mind, here's a fun code snippet:

```javascript
class Meme {
  static a() {
    return 1;
  }

  static b() {
    return this.a()
  }
}

const anotherObj = {
  a() {
    return 5
  },
  b: Meme.b,
}

console.log(anotherObj.b()) // 5

```

---

<div class="post-metadata">

### Author: ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)
#### Post date: [August 29, 2021, 3:36pm UTC](https://es.discourse.group/t/assigning-a-static-method-as-an-expression-to-a-variable-results-in-this-as-undefined-why-does-the-this-context-get-lost/953/3 "2021-08-29T15:36:37Z")

</div>

> [@VIEWVIEWVIEW](#):
>
> ```javascript
> class Meme {
> static a() {
> return 1;
> }
> 
> static b() {
> return this.a()
> }
> }
> 
> ```

Another way to reason about this code is that it is effectively the same as this:

```javascript
function _a() { return 1; }
function _b() { return this.a(); }

function Meme() {}
Meme.a = _a;
Meme.b = _b;

```

---

<div class="post-metadata">

### Author: ![VIEWVIEWVIEW](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/viewviewview/32/986_2.png) [@VIEWVIEWVIEW](https://es.discourse.group/u/VIEWVIEWVIEW)
#### Post date: [September 3, 2021, 5:12pm UTC](https://es.discourse.group/t/assigning-a-static-method-as-an-expression-to-a-variable-results-in-this-as-undefined-why-does-the-this-context-get-lost/953/4 "2021-09-03T17:12:12Z")

</div>

Thank you two.  
Honestly, it felt quite counter-intuitive at first, and I totally forgot that I could just use an arrow function for that. Mea culpa 😅

Just for completeness:

```javascript
class Meme {
  static a() {
    return 1;
  }

  static b() {
    return this.a()
  }
}

// const testB = Meme.b // <- don't use this
const testB = () => Meme.b // <- use this

testB() // output: 1 ✅ 

```

Works like charm now! Thanks again! :)

---

<div class="post-metadata">

### Author: ![senocular](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/senocular/32/642_2.png) [@senocular](https://es.discourse.group/u/senocular)
#### Post date: [September 3, 2021, 11:06pm UTC](https://es.discourse.group/t/assigning-a-static-method-as-an-expression-to-a-variable-results-in-this-as-undefined-why-does-the-this-context-get-lost/953/5 "2021-09-03T23:06:46Z")

</div>

You can use an arrow function in a static field too

```javascript
class Meme {
  static a() {
    return 1;
  }

  static b = () => {
    return this.a()
  }
}

const testB = Meme.b

testB() // output: 1 ✅ 

```
