# Function nodes and \`let\` for variables

**URL:** <https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679>\
**Category:** General\
**Created:** [18 March 2023 00:33 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679 "2023-03-18T00:33:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 00:33 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/1 "2023-03-18T00:33:09Z")

</div>

If I am not mistaken when you use _variables_ you need to _declare_ them at the start.

In the olden days it was:  
`var x = "foo";`

This evolved into:  
`let x = "foo";`

And so the question arises:  
I am writing in a `function` node and I need multiple outputs.  
`msg1` and `msg2`  
I'll supply screen shots only because they make what caught me more obvious:  
And so I would expect to write the code as shown......  
Note the error shown to me by the editor. (The small ~ under the `.` after `msg2` and the `let` at the start - as per the line above. Which does NOT give an error.

 ![Screenshot from 2023-03-18 11-20-49](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/f/5fb35e19ee38c61499925a56d2cd049eba9cc964.png)

And so I do this.

 ![Screenshot from 2023-03-18 11-20-38](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/6/c6386c6e61eea4a75310dd8686af3dd7aab48eff.png)

So why is it that _it_ is accepting the`let` on the first line and NOT on the second?

---

<div class="post-metadata">

**Author:** ![Sean-McG](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/sean-mcg/32/54677_2.png) [@Sean-McG](https://discourse.nodered.org/u/Sean-McG)\
**Post date:** [18 March 2023 00:50 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/2 "2023-03-18T00:50:27Z")

</div>

It doesn't trigger a syntax error, but it will not work like that if you try to send msg2, you will find its not defined.

So as you already know it should be in the format of `let msg2= {reset:false}`

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [18 March 2023 00:54 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/3 "2023-03-18T00:54:42Z")

</div>

> [@Trying\_to\_learn](#):
>
> If I am not mistaken when you use _variables_ you need to _declare_ them at the start

Not really. You can define them when you need them.

> [@Trying\_to\_learn](#):
>
> In the olden days it was:  
> `var x = "foo";`
> 
> This evolved into:  
> `let x = "foo";`

No, both still exist. And you forgot `const` 🙂

`let` and `const` define variables locally whereas `var` is always "hoisted" to the start of the program.

You need to remember that let and const are consttrained to the code block where they are defined. For example, if you define one inside the code block of an if statement, the variable only exists inside that block.

* * *

But this is not your issue. Your issue is that to assign a property to an object, you need to tell JavaScript that the variable IS an object. So you need a `const msg2 = {}` before assigning something to msg2.reset.

Or you can do it as suggested by smcgann99. 🙂

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 01:07 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/4 "2023-03-18T01:07:20Z")

</div>

(Bashes head against the brick wall)

Thanks.

I need to study `let` and `var` and `const` and get them clear in my mind to what they mean/do.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 05:39 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/5 "2023-03-18T05:39:04Z")

</div>

So (sorry: just wasted 3 hours writing code and it died miserably.)

> [@TotallyInformation](#):
>
> You need to remember that let and const are consttrained to the code block where they are defined. For example, if you define one inside the code block of an if statement, the variable only exists inside that block.

Forgive the pathetic attempt to check this:

```auto
var x = "this is x";
if (x == "something")
{
      let y = "this is y";
      var z = "this is z";
      // var `x` is/not? visible here?
}
// Is `y` visible here?
// Is `z` visible here?

```

Now to help me - I hope no end - could you confirm this theory?  
inside the `if{}` part, can I have another `x` variable which is isolated from the _something_ `x` defined outside the part.

This is sort of arcing back to when I did `Arduino` stuff. I never really got the hang of it either.  
(Gotta start somewhere)

I'm guessing `x` will be visible within the `if{}` as it is declared _outside_ that group/routine.  
But I am not sure.  
I seem to remember with the arduino code: subroutines did NOT see external variables UNLESS they were defined as GLOBAL.

I'll stop digging now.  
The hole is big enough just now.

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [18 March 2023 07:30 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/6 "2023-03-18T07:30:11Z")

</div>

This how ChatGPT explains it...

In JavaScript, the scope of a variable refers to the accessibility of that variable within different parts of a program. There are three types of scope in JavaScript:

1. Global scope: A variable declared outside a function or a block of code has a global scope, meaning it can be accessed from anywhere within the program.
2. Local scope: A variable declared inside a function or a block of code has a local scope, meaning it can only be accessed within that function or block of code.
3. Block scope: A variable declared with the `let` or `const` keywords inside a block of code, such as a loop or an if statement, has a block scope, meaning it can only be accessed within that block of code.

Variables declared with the `var` keyword have function scope, which means they are accessible within the function in which they are declared, as well as any nested functions. However, variables declared with `let` and `const` have block scope, which means they are only accessible within the block of code in which they are declared, including any nested blocks.

It's important to be aware of variable scope when writing JavaScript code to avoid unexpected behavior and potential bugs.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 07:44 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/7 "2023-03-18T07:44:08Z")

</div>

Thanks Dave.

I fear I am not able to parse that to something I can use.

I get that Node-red uses JavaScript, and `function` nodes are a big way into that area.  
But that's about the limit of my knowledge.

I don't use _subroutines_ (well ok, maybe a couple of times, but they were extreme) and so a lot of what you just said is out of context. (Sorry)

I kind of have my head around the _context_ levels in NR.

Global, flow and node.

Could you equate those names to those terms?

(My geuss/attempt)

Global = global.  
Local = flow.  
Block = node.

# Ok, you added more after I started replying.

So you kind of did confirm what I just asked.

## BUT

(sorry)

All of that is with `var`. Not `let` or the new _kid_ `const`.  
Where/how do the other two fit in that scheme?

Last minute thought:  
`const`  
That is sent ONCE in the code (per execution) and doesn't / can't change until the code is complete.  
Yes?

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [18 March 2023 07:47 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/8 "2023-03-18T07:47:36Z")

</div>

The example code I posted would need to be "adjusted/edited" to make it work in Node-RED.  
I didn't mean for it to be used - it was meant to be a visual example only.

EDIT:  
I've removed the example code as I think it might cause confusion.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 07:53 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/9 "2023-03-18T07:53:54Z")

</div>

I get that is an example.

I am just trying to get a baseline which shows me an example from which I can build.

Oh, I just saw the edit pop up where you removed the example.  
I _thought_ it was pretty good..... But you say it may cause confsuion.  
Now I am kind of more confused.

---

<div class="post-metadata">

**Author:** ![dynamicdave](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dynamicdave/32/96_2.png) [@dynamicdave](https://discourse.nodered.org/u/dynamicdave)\
**Post date:** [18 March 2023 08:07 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/10 "2023-03-18T08:07:18Z")

</div>

Sorry if it caused confusion (that was not intended) - I'll try to sort out a better example later.  
In the meantime maybe another forum member might offer a readymade example.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 08:09 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/11 "2023-03-18T08:09:36Z")

</div>

Dave,

No it wasn't confusing. I just didn't understand it all.  
It's my fault/problem.

I thought the example you posted (and deleted) was helpful. But maybe it is/was my stupidity that believed that and it wasn't. I can't say.

I am really just not getting the finer differences between those _terms_:  
`let` `var` and `const`.

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [18 March 2023 08:56 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/12 "2023-03-18T08:56:10Z")

</div>

The key difference between `var` vs `let` and `const`, is that let and const are bound to a "scope" and var is not.

What is are example scopes:

```auto
{ }
function myFunction(){}

```

So if you define:

```auto
{
 var x = "hello"
}
console.log(x) // < outside the scope, produces: hello

```

Try this again with let or const:

```auto
{
let a = "hello"
}
console.log(a) // < outside the scope, produces: Can't find variable a

```

So in short, vars can always be accessed while let and const are only accessible within their scope, which in turn _can_ be global if you define outside and before the scope. Const should be considered as an immutable constant, like Pi. (although it is not true, but to not confuse you any further - assume they are immutable)

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 09:52 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/13 "2023-03-18T09:52:23Z")

</div>

So-o-o-o-o

Just to clarify I understand you correctly..

```auto
{
 var x = "hello"
}
console.log(x) // < outside the scope, produces: hello

```

So if I go:

```auto
var x = "hello";
{
    // x is visible here too - yes?
}

```

If I use `var` to define my variables I am forced to structure _WHERE_ I define the variables.

Where as `let` makes all variables _global_.  
(again) sorry. Just want to check.

So `const` is set at the line where it is set and from then on it can NOT be changed.

Am I getting it?

And I am probably (seeming) to repeat back to you what you just wrote.  
By me doing this it sort of makes/helps it soak into the rocks in my head.

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [18 March 2023 10:10 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/14 "2023-03-18T10:10:49Z")

</div>

> If I use `var` to define my variables I am forced to structure _WHERE_ I define the variables.  
> Where as `let` makes all variables _global_ .

No the other way around: let and const are scoped: in the scope they are declared, they can be used.

Currently the function node within node-red applies 'strict' typing, meaning if you don't define the variables it ends up in error.

Before strict, you were not required to declare variables and could immediately use:

```auto
x = "hello"

```

Which underwater implied: `var x = "hello"`

Now you are required to declare variables, you can still do that with `var`, but `var` is not scoped, meaning it can be hoisted, the term @TotallyInformation referred to: a variable can be used before it has been declared.

Rules of thumb:

- declare variables at the top of the code. (be it in global or local (read: function) scope)
- use const where ever you can.
- don't use var.

Perhaps [this article explains](https://www.w3schools.com/js/js_scope.asp) it better than i can.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 10:44 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/15 "2023-03-18T10:44:15Z")

</div>

I need to step back a bit and look at what you said.

> [@bakman2](#):
>
> So if you define:
> 
> ```auto
> {
> var x = "hello"
> }
> console.log(x) // < outside the scope, produces: hello
> 
> ```
> 
> Try this again with let or const:
> 
> ```auto
> {
> let a = "hello"
> }
> console.log(a) // < outside the scope, produces: Can't find variable a
> 
> ```

As I read that l `let` controls from where in the code the variable can been seen.  
Where as if I used `var` it doesn't seem to matter. (But I digress)

You used `var` in one and `let` in another.  
Adding to my confusion you also changed the structure of the two examples.

I don't want to drag this on more than it needs to.  
Yes, I could try it locally, but in case anyone else is stuck like me.

```auto
{
    var x = "hello";
}
console.log(x) // Will give "hello".

```

So what would happen in these examples:

One:

```auto
var x = "hello";
{
    // Is x visible here?
}

```

Two:

```auto
{
     let x = "hello";
}
// Is x visible here?

```

Lucky last:

```auto
let x = "hello";
{
    // Is x visible here?
}

```

I don't know how to do what you showed as I don't have `javascrpit` installed - AFAIK.  
And/or I don't know how to open a console.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 11:07 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/16 "2023-03-18T11:07:41Z")

</div>

# UPDATE:

Ok, I made a bit of a flow and it does show me the subtle differences between `var` and `let`.

```auto
[{"id":"863368aec398661f","type":"debug","z":"aaa025a7d2bb5b14","name":"debug 73","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1080,"y":2390,"wires":[]},{"id":"37d5b43fd4c7dbc1","type":"inject","z":"aaa025a7d2bb5b14","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":720,"y":2390,"wires":[["24ee0b11388d213a"]]},{"id":"24ee0b11388d213a","type":"function","z":"aaa025a7d2bb5b14","name":"LET 2","func":"let y = 1;\nif (y == 1) {\n let x = \"this is x\";\n}\nnode.warn(x);\nreturn msg;","outputs":1,"noerr":2,"initialize":"","finalize":"","libs":[],"x":870,"y":2390,"wires":[["863368aec398661f"]]},{"id":"16c28cb6e2408066","type":"function","z":"aaa025a7d2bb5b14","name":"VAR","func":"var x = \"this is x\";\nvar y = 1;\nif (y == 1) {\n node.warn(x);\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":870,"y":2460,"wires":[["a2721de0f2033386"]]},{"id":"ea7f22d533827b5b","type":"inject","z":"aaa025a7d2bb5b14","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":720,"y":2460,"wires":[["16c28cb6e2408066"]]},{"id":"a2721de0f2033386","type":"debug","z":"aaa025a7d2bb5b14","name":"debug 74","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1080,"y":2460,"wires":[]},{"id":"8b794dc1920420fe","type":"function","z":"aaa025a7d2bb5b14","name":"VAR 2","func":"var y = 1;\nif (y == 1) {\n var x = \"this is x\";\n}\nnode.warn(x);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":870,"y":2520,"wires":[["3c57e7a81925dc7a"]]},{"id":"5d1aa170893e0389","type":"inject","z":"aaa025a7d2bb5b14","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":720,"y":2520,"wires":[["8b794dc1920420fe"]]},{"id":"3c57e7a81925dc7a","type":"debug","z":"aaa025a7d2bb5b14","name":"debug 75","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1080,"y":2520,"wires":[]},{"id":"7d491892ce323b49","type":"function","z":"aaa025a7d2bb5b14","name":"LET","func":"let x = \"this is x\";\nlet y = 1;\nif (y == 1)\n{\n node.warn(x);\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":870,"y":2320,"wires":[["c00e6fbf46ad97b4"]]},{"id":"6f74944952c5411f","type":"inject","z":"aaa025a7d2bb5b14","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":720,"y":2320,"wires":[["7d491892ce323b49"]]},{"id":"c00e6fbf46ad97b4","type":"debug","z":"aaa025a7d2bb5b14","name":"debug 76","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1080,"y":2320,"wires":[]}]

```

It seems to confirm what I thought.

`let` is better to make/force you to structure the code better.  
If you want variables to be seen everywhere in the code, put them at the _base_ of the code.  
If you put them inside `{ `}`they are only visible within that`{ }`.

---

<div class="post-metadata">

**Author:** ![bakman2](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bakman2/32/6207_2.png) [@bakman2](https://discourse.nodered.org/u/bakman2)\
**Post date:** [18 March 2023 11:08 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/17 "2023-03-18T11:08:45Z")

</div>

> [@Trying\_to\_learn](#):
>
> don't know how to do what you showed as I don't have `javascrpit` installed - AFAIK.

You have it directly available in the browser. Right click on a page -\> inspect element and then go to the console tab. You can enter javascript right there.

To answer your questions:  
one: yes  
two: no  
lucky last: yes.

Note that if you use the browser console; use unique variable names, else you might be using/conflicting variables with unexpected outcomes.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 11:12 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/18 "2023-03-18T11:12:09Z")

</div>

I am only wanting to get my head around the _scope_ of `let` and `var`.

Seems I now know it.

Now `const` is/can only be set once per pass of the code.  
But is it at the `let` or `var` scope?

---

<div class="post-metadata">

**Author:** ![kevinGodell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kevingodell/32/27040_2.png) [@kevinGodell](https://discourse.nodered.org/u/kevinGodell)\
**Post date:** [18 March 2023 11:14 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/19 "2023-03-18T11:14:11Z")

</div>

Use `const`, unless you have to use `let`.  
Only use `var` if you are maintaining old legacy code and it is already filled with lots of vars and you don't have time to do a complete refactor.

When using const, you will quickly be met with an error letting you know that you cannot redefine the value. In that case, switch to using let.

---

<div class="post-metadata">

**Author:** ![Trying\_to\_learn](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/trying_to_learn/32/28400_2.png) [@Trying\_to\_learn](https://discourse.nodered.org/u/Trying_to_learn)\
**Post date:** [18 March 2023 11:21 UTC](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679/20 "2023-03-18T11:21:05Z")

</div>

Thanks.

I am still not able to explain how I think _how_ I see variables.

`let` or `var` are things that can be changed during the code's execution.

eg:

```auto
let x = msg.payload;
if (x == 10)
{
     x = x + 10;
}
msg.payload = x;
return msg;

```

Another way to write that would be - example:

```auto
const x = msg.payload;
let y = 0;
if (x == 10)
{
    y = x + 10;
}
msg.payload = y;
return msg;

```

Yes?

This is AN EXAMPLE of how to use `const`

[Next page](https://discourse.nodered.org/t/function-nodes-and-let-for-variables/76679.md?page=2)
