0

I have two .js files: root.js and external.js

root.js

import myExternalFunction from 'external.js'

class Parent {
    constructor(){}
    parentFunction = () => {
        console.log('I was called from an external function using "this."')
    }
}

external.js

export default myExternalFunction = () => {
    this.parentFunction()
}

Currently I receive an error about it not being a function, or no access to 'this'.

How do I import external functions that want to use the 'this' scope from which they are being called?

sadhucoder
  • 190
  • 1
  • 8
  • 1
    That's invalid JS, you cannot have an arrow function inside a `class`. – Bergi Jul 23 '17 at 17:32
  • 1
    Given that `myExternalFunction` isn't passed an instance of `Parent`, what specifically are you expecting? How is it supposed to know what `parentFunction` you want called? – loganfsmyth Jul 23 '17 at 17:54
  • @Bergi I use arrow functions in classes on a regular basis, and it works plainly. – sadhucoder Jul 23 '17 at 18:39
  • @loganfsmyth I don't want my external function to know about my `Parent` When my Parent imports this external function, I want it to be able to use it. Kind of like prototyping a method, or using a functional utility library like underscore. I want the `Parent` to call this imported function `myExternalFunction`, and have the function be aware of "this" scope, since it's now imported. I have also tried `myImportedFunction = myExternalFunction` in `Parent`, but it didn't work. – sadhucoder Jul 23 '17 at 18:45
  • @sadhucoder Well it's not an ES6 `class` for sure, however there exist babel plugins for experimental syntax that moves property assignments outside of the constructor – Bergi Jul 23 '17 at 20:36
  • Arrow functions called with `obj.fn()` explicitly don't use the value of `this` from `obj` so the value of `this` will be the lexical `this`, not the object `this`. Stop using arrow functions for methods of an object. – jfriend00 Jul 23 '17 at 22:24
  • @Bergi Gotcha. I could see a Babel transform changing things in a way I don't understand yet. I'll look into it, thanks! – sadhucoder Jul 24 '17 at 04:46

1 Answers1

0

How do I import external functions that want to use the 'this' scope from which they are being called?

It doesn't have anything to do with how you export/import the function.

There are two things you need to consider:

  • functions that want to receive their this value dynamically must not be arrow functions, so use

    export default function myExternalFunction() {
        this.parentFunction()
    }
    
  • as usual, the function must be invoked in the right way to get the expected this value. There's no magic that passes the current this value in the scope of the call to the called function. You'll have to do something like

    import myExternalFunction from 'external.js'
    
    class Parent {
        constructor(){
            this.method = myExternalFunction;
            this.parentFunction = () => {
                console.log('I was called from an external function using "this."')
            }
        }
    }
    
    const example = new Parent;
    example.method() // an invocation as a method
    myExternalFunction.call(example); // explicit using `call`
    
Bergi
  • 513,640
  • 108
  • 821
  • 1,164