Use Global Variable In Same File As It's Declared? - javascript

Is it possible to use a global variable in the same file that it is declared?
The following code does not throw a compiletime error:
declare global {
const something = "something goes here";
}
export default {
somethingElse: something + " else"
}
However, it seems to be causing an 'undefined variable' error in the same file and every other file I use it in.

TypeScript's declare syntax is used to declare variables that already exist globally in the context of a module. For instance, in a web application where variables might be coming from <script> tags that TypeScript isn't aware of, said variables and their types can be declared so that their use can be type checked.
Therefore, TypeScript wouldn't warn you about something being undefined, as it expects the variable to already have been declared elsewhere, and your declare global {} block to be informing it of said declaration.

Related

Unacaught process is not defined even when used inside an if (process) {} block? [duplicate]

This question already has answers here:
How to check a not-defined variable in JavaScript
(15 answers)
Closed 3 years ago.
So I'm trying to swap between API links in my angular app based on the origin, but it is an SSR app so I'm trying to account for an environment variable as well as window location, the code is as follows:
const getApiUrl = (): string => {
if (process && process.env?.AZURE_ENV === 'development') {
return 'devlink for SSR';
} else if (
window &&
window.location.origin === 'devclient'
) {
return 'devlink for frontendclient';
} else {
return 'link.com/';
}
};
Now the error being thrown out is:
Uncaught ReferenceError: process is not defined
I've digged into the 'compiled' script and have 100% confirmed it's coming from this piece of code.
Shouldn't this still work though?
I've also tried a vesion where I just have if(process) and get the exact same result as above.
Probably it is not there so it will fail to evaluate, maybe testing it like typeof process !== 'undefined' will help
If process has never been defined in any accessible context I think it will fail with an UncaughtReferenceError because it is trying to access something not in the context. Undefined means that the variable exists but it has no value set and this error says that the variable is just not there, thats why checkinng the type of it will probably solve the issue.
Nope. While a non-exising field of an object is really undefined, read access to a non-existing variable is an error in JavaScript, use typeof as other answers suggest...
console.log("typeof {}.process",typeof {}.process);
console.log("typeof process",typeof process);
console.log("{}.process",{}.process);
console.log("process",process);
... also, your code is TypeScript, the :string part gives it away. Which means it is compiled to strict mode, and even write access to a non-existing non-local variable would be an error.
I'm not very familiar with angular. But typically this is supposed to be client side code and it doesn't have access to node environment variables. Even if it is SSR.
If you are using webpack you could define the environment variable as a global variable on the client side:
https://webpack.js.org/plugins/define-plugin/
For your case if you don't want to use any other solutions, firstly check global , its like window but on node, so process will be stored in global.process

Getting variable reference errors after implementing es6 modules

I'm trying to clean up my code and implement es6 modules for the first time. I have created three module files and am using the import/export keyword where necessary and have specified type="module" in index.html.
The problem is everything functions correctly except all the global variables are undefined in my main file and now I get Reference Errors: Variable not defined if I try to console.log(variable)in the console. Confusing me further is if I place the same console.log(variable) inside an IIFE within the file it correctly displays the variable value with no Reference Error.
For example:
<script type="module">
let foo = "some text";
(function() {
console.log(foo)
}()); // prints "some text"
console.log(foo); // prints Reference Error: foo not defined
</script>
Are there special rules for how global variables are handled in es6 modules? I'm just really confused because the everything else works properly and all I changed was splitting my file using es6 modules and running a local server (because of CORS error from using module pattern).
It appears my issue was a misunderstanding of how the console works and that it doesn't have access to a variable within a module file unless it is made global by attaching it to window.
For example, this now allows me to access the variable in question:
let foo = "some text";
window.foo = foo;
console.log(foo); // now prints "some text" in the console instead of Reference Error
Related answers:
How to access functions defined in es6 module in a browsers javascript console
What is the correct way to define global variable in ES6 modules?

ESlint rule that detects that a variable and a function has the same name in Javascript?

I happened to name a variable the same as a function in Node.js. This did not go very well, Node 10 did not like it. And since this was a hook function (not called from the UI of the app) it took some time before I discovered what went wrong.
Is there some ESLint rule that can discover these type of bugs? This is under Firebase and and ESLint is run during the deploy to production server.
The actual conflicting use of the variable name was in the same block, something like this: const a = a(x).
I don't think a tool like this could exist for JavaScript, as JavaScript doesn't really disambiguate the type of object assigned to the variable.
function a() {
}
... is basically equivalent to:
var a = function () {
};
Additionally, the value of a in this example can be reassigned later.
A linter may help you, and there may be some help in some IDEs, but they won't truly know the intention of the programmer.
There is a no-redeclare rule you can set in ESLint, which tells you the problematic line in your code.
/*eslint no-redeclare: "error"*/
function a() {}
const a = a();
=> 4:5 error 'a' is already defined no-redeclare
Also ESLint will raises an error with the standard configuration.
function a() {}
var a = a();
=> 4:5 error Parsing error: Identifier 'a' has already been declared
Of course, with const, you will get a syntax error with the line as well if you try to run your script.

Const behaviour if require fails

Opening the node repl (v6.6.0) and doing:
> const test = require('somethingGuaranteedToFail');
Error: Cannot find module 'somethingGuaranteedToFail'
Now the variable test can neither be redefined, nor has it been properly initialized.
> console.log(typeof test);
ReferenceError: test is not defined
> const test = 1;
TypeError: Identifier 'test' has already been declared
It seems to happen with anything that throws an error during assignment, not just require.
I guess the question is, is this expected behaviour? I would have thought the const variable would at least contain the Error object.
I guess the question is, is this expected behaviour?
Yes. A const cannot be redefined or redeclared. const test declared it, but failed to define it because an error was raised.
I would have thought the const variable would at least contain the Error object.
require does not return an error, it throws one. If you want it, you need to catch it.
Yes, this is expected the behavior. If you throw an exception, the test variable will never initialize. This is also the case for something like
var getTest;
try {
getTest = function(){
return test;
};
throw new Error();
const test = 'a string';
} catch (e){
// ignore the error
}
getTest();
The final call to getTest will attempt to access test, which was never initialized because the exception caused the string value to never be assigned. It will never be assigned the Error object, because the initialization of test is unrelated to the exception.
I don't know if this is a bug, but regardless of whether it's intended or not, this behavior can only occur in a REPL environment.
The reason is that, unlike var, const is block-scoped, but if you try to assign the result of a require statement that throws an exception to it (e.g., when the module resolution fails), an exception will be thrown and execution will leave the scope of the block, so the variable falls out of scope. Since you can't stay in the same scope as the variable is defined after an exception is thrown, you cannot redefine a new const variable in the same scope.
However, in the REPL environment, you don't leave the same scope when an exception fails, therefore you can end up in a situation where a failed const declaration is still in scope, so node refuses to redeclare it.

javascript global variables visibility

I'm using a global variable in javascript, declared in a script tag outside any function:
<script type="text/javascript">
var prov_status_dict={};
....
</script>
Later on in a javascript method I'm using the variable normally.
temp=prov_status_dict[current_as_id];
I'm having issues with it on opera and ie, while on firefox it works. This is what opera's error console reports:
JavaScript - http://localhost:8000/input/
Event thread: click
Error:
name: ReferenceError
message: Statement on line 62: Undefined variable: prov_status_dict
stacktrace: n/a; see opera:config#UserPrefs|Exceptions Have Stacktrace
I've noticed that the problem is with global variables in general. I tryed moving some into hidden fields, but the same error pops up on the next use of a global var.
Help?
I usually access my globals through the window object so that I always have a point of reference
window.MyVariables = {};
window.MyVariables.prov_status_dict = {};
Give this a try, it might resolve your problem.
Try to avoid using global variables, see http://yuiblog.com/blog/2006/06/01/global-domination

Categories

Resources