1

I understand that var is a global variable in node js and it can be accessed everywhere.

However I was confused by below examples

In below, global_1 can be accessed without confusion, as it is global variable.

var global_1 =1 

function2 = () => {

console.log('global_1 in function2: ' + global_1)

}

main = () =>{

console.log('global_1 in main: ' + global_1)

function2()

}

main()

But if I put my function2 inside a help.js ; it said global_1 is undefined ; isnt it that when I import helper function, the effect is same as the above code where I paste my function2 in the same file?

const helper = require('./helper'); 

var global_1 =1 

main = () =>{

console.log('global_1 in main: ' + global_1)

helper.function2()

}

main()

As for let and const, my understanding is that they can only be accessed within a {} 

But now, global_1 is still be able to be accessed by function2, even though global_1 is not defined inside function2. Isnt it only var can be accessed everywhere and let,const can only be access within {} ?

var global_1 =1 


or  let global_1 =1 

or  const global_1 =1 



function2 = () => {

console.log('global_1 in function2: ' + global_1)

}

main = () =>{

console.log('global_1 in main: ' + global_1)

function2()

}

main()
  • 2
    *"I understand that var is a global variable in node js and it can be accessed everywhere."* That's not correct. In the normal case (when you do `node somefile.js` or when you `require` or `import` it in another file), Node.js runs your code as a module, not as a global script. Top-level declarations in a module are only global within that module, not (er) globally. – T.J. Crowder Mar 08 '22 at 10:35
  • Thanks , when you require or import it in another file), Node.js runs your code as a module; What does it mean? you mean that it is like in Java, the running point will jump to other file(module) to continue to run the code? –  Mar 08 '22 at 13:50
  • 1
    Modules have their own scope, which is different from (but similar to) the scope within a function. `var` and function declarations are private to the module in which they appear, they aren't globals. (As are top-level `let`, `const`, and `class` declarations. When those *aren't* at the top level, they're more narrowly scoped.) – T.J. Crowder Mar 08 '22 at 14:20

1 Answers1

2

I understand that var is a global variable in node js and it can be accessed everywhere.

You're wrong.

var inside a function declares a variable scoped to that function.

var outside of a function declares a variable scoped to that module.

(There's an edge case, that T.J. pointed out, where if you run the code in the global context (e.g. node < yourModule.js) instead of loading it as a normal module (node yourModule.js) then it won't be treated as a module and var outside a function will create a global).

But if I put my function2 inside a help.js ; it said global_1 is undefined ; isnt it that when I import helper function, the effect is same as the above code where I paste my function2 in the same file?

No.

The variables that are "in scope" are determined by where a function is defined, not by where it is called.

As for let and const, my understanding is that they can only be accessed within a {} 

No.

They can't be accessed outside of the block in which they are defined.

In your example they are defined outside of any explicit block, do the whole module is treated as the block for these purposes.


var a = 1;

function b () {
    var c = 2;
    let d = 3;
    
    if (a) {
        let e = 4;
        var f = 5;
        // a b c d e and f are available here
    }
    // a b c d and f are available here
    // e isn't because it is block scoped and this is outside the block
}

// a and b are available here.
// Everything else is scoped to either the function b or the block
// connected to the if statement inside it
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 1
    **Much** more complete than mine, I basically skipped the second two-thirds of the question. :-) It may be worth mentioning that you **can** run code at global scope in node by redirecting rather than passing the file as an argument: `node < somefile.js` instead of `node somefile.js`. – T.J. Crowder Mar 08 '22 at 10:35
  • 2
    It would be a bit more polite to say "This is incorrect" rather "You're wrong". – Andy Mar 08 '22 at 10:48
  • 2
    @Andy That's a good point, it's so easy for words to be taken in bad context, especially when it's text based. I'm sure Quentin didn't mean it in a bad way like. ps: I'm pretty sure I've done it a few times too.. – Keith Mar 08 '22 at 11:14
  • 1
    @Keith, I agree. On reflection I probably meant "encouraging" rather than "polite". Words are hard. – Andy Mar 08 '22 at 11:20
  • @Quentin Thanks all, it is fine as long as the answer helps indeed. So, what i was missing is that I should treat module as block and any blocked variable can be accessed not only just within the block, but any blocks(child block) under that the block where its declared. Right? –  Mar 08 '22 at 13:37
  • @Quentin ,but i dont get why f variable is available outside the if block, but not outside the function b –  Mar 09 '22 at 02:17
  • "var inside a function declares a variable scoped to that function." – Quentin Mar 09 '22 at 08:41
  • @T.J.Crowder How can we run an `index.js` file in the global scope? I mean skip treating it like a module? using `node < somefile.js` raise an error `stdin is not a tty` – SeyyedKhandon Dec 11 '22 at 08:48
  • @SeyyedKhandon - That's how you do it. What environment are you doing that in that you get that error? But separately: Why do you want to run something as a non-module? Modules offer a lot of benefits. – T.J. Crowder Dec 11 '22 at 09:53
  • @T.J.Crowder You are right, it works in windows CMD. but in WSL bash it raises that error. Thanks – SeyyedKhandon Dec 11 '22 at 13:08
  • @SeyyedKhandon - Ah, interesting. I wonder if `type somefile.js > node` works? (Don't know if `type` works in WSL bash.) – T.J. Crowder Dec 11 '22 at 14:32
  • @T.J.Crowder It prints a wired error `bash: type: index.js: not found`. the file is in the current directory, I've tested ./index.js , .\index.js but non worked – SeyyedKhandon Dec 11 '22 at 15:02
  • @T.J.Crowder No errors are thrown, but nothing happens or is printed, and it seems to just skip the code execution – SeyyedKhandon Dec 11 '22 at 15:14
  • @SeyyedKhandon - ...and it probably created a `node` file in that directory. Sorry, I had `>` when I meant `|`: `cat index.js | node`. – T.J. Crowder Dec 11 '22 at 15:20
  • @T.J.Crowder The same error `stdin is not a tty` – SeyyedKhandon Dec 12 '22 at 05:37
  • 1
    @SeyyedKhandon - Well, at least that's consistent with `node < index.js`! :-D How very odd. The `node < index.js` thing works in \*nix shells (such as `bash`) and Windows' `cmd.exe` (not PowerShell, it doesn't support `<` [yet]); `type index.js | node` works in Windows' `cmd.exe` and PowerShell, and the \*nix equivalent `cat index.js | node` works in \*nix shells. I'm really surprised WSL bash doesn't work with at least one of them. – T.J. Crowder Dec 12 '22 at 07:28
  • @T.J.Crowder My apologies, I made a mistake. I've used to working with `git`'s bash inside the vscode which is based on `MINGW64` and when I've typed the bash, I thought it would open my ubuntu from wsl, but it didn't. As a result, the problem lies with git bash (MINGW64). – SeyyedKhandon Dec 13 '22 at 08:15