2

i want to understand a little bit more about the javascript reference scope, i was trying to import a function from onother file like this

file1.js

exports.checkIfCan = function(){
 //make some check
}

exports.calculate = function(){
   this.checkIfCan();
}

and using the calculate method with this import

file2.js

const { calculate } = require('./file1.js')

calculate()

actually the error is this.checkIfCan is not a function but if i import all the module like this it works

const calculation = require('./file1.js')

calculation.calculate();

I just wanna understand more about the global/local scope in javascript

Vlad Vlads
  • 23
  • 5
  • You need to check classes instead. You want to create an object with functions on it. Check this: https://stackoverflow.com/questions/5334383/javascript-function-as-an-object-property – Juan Medina Apr 24 '21 at 13:28
  • 1
    I'm not getting any error and both of your cases are working in my case....lol – Abhishek Pankar Apr 24 '21 at 14:04
  • Is `exports.calculate = () => {` definitely using an arrow function, and isn't `exports.calculate = function() {`. Your error seems to suggest that you're not using arrow functions – Nick Parsons Apr 24 '21 at 14:08
  • @NickParsons you're right, i'm not using arrow function, but why it should work with? – Vlad Vlads Apr 24 '21 at 14:24
  • @VladVlads the this keyword works slightly differently in arrow functions than it does within regular functions. – Nick Parsons Apr 24 '21 at 14:29

3 Answers3

2

this refers to the context of the function invocation, which in your case is undefined (on browsers the default is window).

Here's an example as simple as possible to make you understand it:

calculation.calculate(); // <= you are calling calculate from calculation, so 'this' is calculation

calculate(); // <= you are calling calculate from... nothing, so 'this' is undefined

Update: using arrow functions it would work either case because this will be taken from the function's surrounding scope instead of the context, and in the top-level code in a Node module this is equivalent to module.exports.

There's a lot to explain about the thisin javascript, may I suggest you read the free ebook You Don't Know JS: this and Object prototypes? You'll find much more information there.

Giovanni Londero
  • 1,309
  • 1
  • 10
  • 20
  • This would be the case if OP was using regular functions, but since OP is using arrow functions the `this` will be taken from the surrounding scope and not based on how the function is called. – Nick Parsons Apr 24 '21 at 14:05
  • @NickParsons What a fail! You're right, I didn't even read it correctly. I'll either improve my answer or remove it, thanks for pointing it out – Giovanni Londero Apr 24 '21 at 14:16
  • no worries. But it looks like OP has updated their answer, so your answer is good now – Nick Parsons Apr 24 '21 at 14:27
  • 1
    That's great, but still I've added some indication about arrow functions and node. Hope it's comprehensible – Giovanni Londero Apr 24 '21 at 14:37
0

@Vlad Vlads, your problem is in the use of keyword this in your file file file1.js.

In accordance to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this, following behaviour may happen:

The value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called.

With that been said, if you remove the keyword this in your function, following will then works as expected:

const { calculate } = require('./file1.js')

calculate()

Your second example will also works as expected

const calculation = require('./file1.js')

calculation.calculate()
Manifest Man
  • 873
  • 10
  • 16
-1

You should use import instead:

file1.js

function abc() {}

export {
   abc
}

file2.js

import { abc } from 'file1.js';
abc();
Vuth
  • 21
  • 3
  • `import` is ES6 module syntax, which OP isn't using here. `require()` and `module.exports` is fine for CommonJS modules, which is what OP appears to be using here. – Nick Parsons Apr 24 '21 at 14:09
  • maybe he's using, you don't know. if he happen to use it in node.js like he tagged or frameworks like React, Vue, or Angular, then using import is supported and it is where the future is heading. You can't just downvote like this. – Vuth Apr 24 '21 at 14:17
  • The exports object does not exist in ES6 modules, so if the OP was using that then they’d be getting other errors. For what it’s worth the down vote isn’t mine – Nick Parsons Apr 24 '21 at 15:04