Hi @wmelonMan ,
I've seen articles and training courses use different JSON "notations". New developers (including myself) assumed that the different notations were the same, it was just a matter of preference. The writers or trainers do not elaborate any further - perhaps they think it may be too confusing for a beginner?
May be the following examples will help.
Example 1

variables('varData')?['name'] ➡️ C-3PO
variables('varData')['name'] ➡️ C-3PO
variables('varData').name ➡️ C-3PO
Example 2: variables('varData')?['name']
The name property is missing from the data:

variables('varData')?['name'] returns an empty value:

The flow does not produce an error and the flow continues. Your flow may need some logic to handle the empty value (e.g. if it is a value, like age or currency).
Example 3: variables('varData')['name']
The name property is missing from the data:

variables('varData')['name'] ➡️Flow stops with an⛔Error
variables('varData').name ➡️ Flow stops with an⛔Error

However, the error message is actually very useful and tells us that the name property is missing from the data:

'The template language expression 'variables('varData')['name']' cannot be evaluated because property 'name' doesn't exist, available properties are 'height, mass'.
So most of the time in your flows you would use the notation variables('varData')?['name'] .
However, as we have seen there are times when the other notation (variables('varData')['name']) can useful in testing and debugging a flow. You may want to generate an error and stop the flow so that you can identify the error and correct it. You may have mistyped a property or the property may be missing and you are seeing empty data values in your flow. You may need some additional logic to handle the empty or missing values or fix the source data.
I know that @DamoBird365 is quite an expert in this area.
Ellis
____________________________________
If I have answered your question, please mark the post as Solved.
If you like my response, please give it a Thumbs Up.