0

I have an example that appears to me to be identical to the example given in the mozilla docs

const foo = (dispatch) => {
    return {
        name: "Personal Files",
        onSelect: function() {
            dispatch({
                type: MoveDocActionType.ENTER_PARTITION,
                partitionName: this.name
            })
        }
    }
}
console.log(foo(({type, partitionName})=>console.log(partitionName)).onSelect())
// Expected output "Personal Files"

The Mozilla docs example:

const test = {
   prop: 42,
   func: function() {
     return this.prop;
   },
 };

console.log(test.func());
// expected output: 42

However, during actual execution, this is undefined in my case. What am I missing, as this seems to be identical to the docs, so I don't see why I would need to manually call bind or anything like that.

EDIT: Found the answer here

The way I was actually calling the method was closer to this:

const foo = (dispatch) => {
    return {
        name: "Personal Files",
        onSelect: function() {
            dispatch({
                type: MoveDocActionType.ENTER_PARTITION,
                partitionName: this.name
            })
        }
    }
}
const bar = foo(({type, partitionName})=>console.log(partitionName)).onSelect
console.log(bar()

// Expected output "Personal Files"
Jordan Mackie
  • 2,264
  • 4
  • 25
  • 45
  • 2
    use arrow functions, `function` keyword functions don't bind `this` to the enclosing scope, rather, `this` is determined when the call is made – Trash Can Jun 15 '22 at 20:07
  • 1
    "*during actual execution, this is undefined in my case*" [I cannot reproduce it](https://jsbin.com/vusigutobu/edit?js,console). Please provide a [mcve]. – VLAZ Jun 15 '22 at 20:08
  • @Dummy if `onSelect` is an arrow function, typescript doesn't seem to think `this` is bound to anything at all. The docs also seem to suggest otherwise: ``` 'use strict'; var obj = { // does not create a new scope i: 10, b: () => console.log(this.i, this), c: function() { console.log(this.i, this); } } obj.b(); // prints undefined, Window {...} (or the global object) obj.c(); // prints 10, Object {...} ``` – Jordan Mackie Jun 15 '22 at 20:17
  • @Dummy you're completely wrong here. An arrow function would not use the object *currently being instantiated* as the value of `this`, since the 1. that object *does not exist while it's being instantiated*. 2. It's not even the value of `this` even if it the arrow function was instantiated later. See [Methods in ES6 objects: using arrow functions](https://stackoverflow.com/q/31095710) and [Self-references in object literals / initializers](https://stackoverflow.com/q/4616202) – VLAZ Jun 15 '22 at 20:26
  • @VLAZ thank you for pointing this out! It turns out, my problem was that I wasn't actual calling the object the way I showed, and was passing the method reference to something else that would call it. So when it was eventually called, this was indeed `undefined`. – Jordan Mackie Jun 15 '22 at 20:28
  • 1
    See [How does the "this" keyword work?](https://stackoverflow.com/q/3127429) and [How to access the correct `this` inside a callback](https://stackoverflow.com/q/20279484). Yes, dissociating the call from the the object it's called *on* would give you the wrong value of `this`. With your code [something like this](https://jsbin.com/qudakudawo/edit?js,console) would work to keep the call with the object it's called on. Or [like so](https://jsbin.com/xopirehibo/1/edit?js,console) to make it not depend on `this`. – VLAZ Jun 15 '22 at 20:51

1 Answers1

-1

If you remove the first console.log, it works for me :

<script type="text/javascript">
const foo = (dispatch) => {
    return {
        name: "Personal Files",
        onSelect: function() {
            dispatch({
                type: "Toto",
                partitionName: this.name
            })
        }
    }
}
foo(({type, partitionName})=>console.log(partitionName)).onSelect()
</script>
  • 1
    The `undefined` printed in the console from the outer `console.log()` is ***not*** the value of `this` inside `onSelect` – VLAZ Jun 15 '22 at 20:35