Why Javascript import function returns undefined - javascript

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

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.

#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()

You should use import instead:
file1.js
function abc() {}
export {
abc
}
file2.js
import { abc } from 'file1.js';
abc();

Related

Unused Functions Not Recognized In Window

Working in ReactJS, I run into an issue where imported functions that are 'unused' are failing to be recognized by the program and I believe are not being added to the window.
In my case, I'm trying to be able to import functions from other files and then call them by string name.
Ex)
import {myFunction} from '../otherFile';
functionNameString = 'myFunction'
window[functionNameString]() //call function by it's string name
//ERROR: window[functionNameString] is not a function
Without changing my above syntax, I've found two ways I can resolve this:
Add the actual function to the same file as the window[functionNameString]() call
Explicitly assign the function to the window at the top of my file like window.myFunction = myFunction
I'm trying to avoid the first case to keep this file shorter, but also don't understand why I need to do the explicit assignment of the function to the window as shown in the second case (and why defining the function in the same file doesn't need this)
Overall, my question is how can I avoid this explicit assignment of and have these imported functions callable from import (or in a shorter syntax)? Assigning like so is fine for a function or two, but I'm looking at importing 15 funcs from this other file which makes things messy working in this fashion. Thanks!
Modules have their own scope, they aren't at global scope, and imports are created as bindings within the module scope, not globals. That's at least half the point of modules: to not make everything global anymore.
Overall, my question is how can I avoid this explicit assignment of and have these imported functions callable?
They are callable. myFunction() will call your function in your example code. There's no reason whatsoever for window to be involved.
If you need to refer to them by a name in a string for some reason, you can put them in an object:
const functions = {
myFunction,
// ...
};
Then functions[functionNameString]() will work.

Declaring a function in ES6?

I wanted to "update" my javascript code to the new ES6 Standard, so I looked at how functions are now written and tried it out on a global function of mine, which reads like this in the "old" es5
function logMessage(message) {
document.getElementById("logs").innerHTML = document.getElementById("logs").innerHTML + `<li class="item-padding"> ${message} </li>`
}
now if I'm not wrong the correct "transformation" to ES6 would be like this:
logMessage = message => {
etc
}
But my ESLint tells me that my logMessage is not defined and I get an error in my console, do I miss something? Do I have to declare var, let or const before the logMessage?
I don't know if its important, but I also want to export this function from file One to file Two and use the function logMessage in another function in file Two, is there something I have to keep in mind when doing so?
Thanks for any help!
Edit: Thanks everyone the answers helped me a lot, got my problem fixed!
function logMessage(message) {
// etc...
}
... is function declaration which is still perfectly valid in es6. You are converting your function declaration into a function expression, which in es5 would look like this...
logMessage = function(message) {
// etc...
}
... and then into es6 ...
logMessage = message => {
// etc
}
... so the linting problem is not introduced by es6 syntax, but rather using function expression, assigning to a variable which without var/let/const is a global variable. There is also a difference in the original function declaration would be hoisted, but the function expression form must be declared before it's called. There is also a difference in that es6 arrow functions retain the context of this from the parent scope, so worth noting they are not 100% direct 1 for 1 mappings of each other.
Short answer, yes, variables need to be declared with var/let/const in order to avoid becoming global variables, whether it's a function or not.
let logMessage = message => {
// etc
}
now if I'm not wrong the correct "transformation" to es6 would be like this
You're wrong.
Arrow functions are a new syntax with different behaviour. They are not a straight up replacement for function declarations and function expressions (both of which still exist in ES6).
But my ESLint tells me that my logMessage is not defined and I get an error in my console, do I miss something? Do I have to declare var, let or const before the logMessage?
Yes. You're assigning something to a variable. You must declare the variable first.
I also want to export this function from file One to file Two
How you define the function has no bearing on your ability to export it.

function ()() in javascript

I am not sure how to call/frame this question title, but can anyone explain me what does the below code do?
var routes = require("./routes/routes.js")(app);
I am seeing a second () with app being passed, what does that do?
https://github.com/couchbaselabs/restful-angularjs-nodejs/blob/master/app.js
To my surprise, in the code above the variable routes is not at all used in app.js? what's the purpose. I am quite confused here does (app) argument do anything magic here?
The construct
foo()();
expects that foo() returns a function and calls it immediately. It's equivalent to the more readable:
var func = foo();
func();
A similar construct you'll often see is:
(function() {
// function definition
})(args);
This defines a function and calls it immediately. The primary use is to emulate block scope for variables.

Why are there two different ways to create functions in Javascript?

In my code I have the following:
var setTheme = function (color) {
};
function setTheme(color) {
};
The function names are not really the same but I have put the same here. Is there a difference in the two ways of creating a function?
There is a difference. With a function definition, the entire definition is hoisted:
foo(5); // Pops up 5
function foo(n) {
alert(n);
}
Whereas with var, the declaration is hoisted but the assignment is not:
foo(5); // Error!
var foo = function(n) {
alert(n);
};
Another difference I noticed is that on Google Chrome Canary (currently and at least, I haven't tried in many other browsers) in ECMAScript 5 strict mode, a function definition cannot be nested more than one level deep:
!function() {
'use strict';
function Blah() {
function Lol() { // Error.
}
}
}();
So,
JS function for get set
var setTheme = function (color) {
};
If you need a private utility for getting/setting/deleting model values then you can declare a function as a variable like this. This could be useful for assigning a variable upon declaration calculated by a function.
For: simple version
function setTheme(color) {
};
This is the simplest way to declare a function in JavaScript. Say for example, we want to write a simple function called setTheme(color) which simply takes in one parameter color, does a simple color on the object or returns the value. Here are a few ways you might go about doing exactly this.
5 Different ways: interesting read:
http://www.jquery4u.com/jquery-functions/5-ways-declare-functions-jquery/
This has been answered many times. There are many ways to call these. As I understand, the first one is a function assignment, the second one is a function declaration. The first one will hoist setTheme to the top of the closest scope but it won't be defined as a function till it gets where it's actually assigned. The second one will hoist the function setTheme up top so you'll be able to use this function even before it's been declared. IMO, use always the first one.

Unable to use Global Variables while trying to use multiple functions - JavaScript - Beginner

As total JavaScript beginner I am unable to use global variable while trying to use multiple functions. The code is as follows -
<script type="text/javascript">
/* Global Variable example! Not working as one function called onClick. */
function make_name_variable () { var y_name = document.getElementById('y_name').value; }
function make_date_variable () { var y_date = document.getElementById('y_date').value; }
function make_month_variable () { var y_month = document.getElementById('y_month').value; }
function make_year_variable () { var y_year = document.getElementById('y_year').value; }
function test(){
/*var y_name = document.getElementById('y_name').value;
var y_date = document.getElementById('y_date').value;
var y_month = document.getElementById('y_month').value;
var y_year = document.getElementById('y_year').value;*/
document.getElementById('Result').innerHTML = y_date + y_month + y_year;
return true;
}
function compute () {
make_name_variable ();
make_date_variable ();
make_month_variable ();
make_year_variable ();
test();
}
</script>
Using as:-
<input type="submit" value="Submit" onclick="compute ()">
Unable to get the result as expected. I want to use the data through out the page so wanted to keep it global for all functions to use. I was not able to set it global in the conventional way as well. Declaring the variable within function gives desired result.
As you must have a realized I am a complete noob so if there are other ways to get the things done please enlighten me. Somehow I feel there must be a better and easier way to solve this.
Thanks in advance. :)
P.S: First question here. Excuse my mistakes.
The var keyword declares a variable in the current scope. If you declare a var inside a function, it will only exist there. The MDN docs are generally very nice.
A GOOD way to declare a global variable in Javascript would be window.globalVariableName rather than var globalVariableName; Or if you are not running your application in browser replace window with global object specific to that invironment.
The first declaration will work no matter where you are in global scope or in a function.
A BAD way to declare a global variable is
globalVariableName = 'Foo';
Because it isn't an obvious declaration and looks a lot like just forgetting the var.
And finally globalVariables is not a good thing to use. So use them thoughtfully. Try to check if they are not used already by another script say like that
if(window.globalVariableName === undefined) window.globalVariableName = 'Bar';
Try reading first chapter of
JavaScript Patterns
Stoyan Stefanov
for more explanation.
UPDATE: awsering Andreas Rossberg
For example David Flanigan in Definitive Javascript Guide states in 4.6.1 what are global variables, they are properties of the global object. You can confirm this on MDN also.
About bad style, i can agree but only partially, because if you don't use the Single var Pattern for variable declarations like this
(function(){
var someVar1 = '',
someVar2 = null,
someVar3 = undefined;
})();
your code will look just as bad.
As to next version of EcmaScript again you are a little too brief on reference. I've read only that this will be handled differently in strict Javascript. If I understood you correctly this example is what you are referring to
function someFunction()
{
//'use strict';
console.log(this); //Window or undefined
console.log(window);// Window or Window
}
someFunction();
Uncommenting 'use strict'; will give undefined for this in first log, but still Window for the second log.

Categories