0

First I linked two JavaScript files to my HTML

<script src="script.js"></script>  
<script src="main.js"></script>

On the first file ( the "script.js" file) I wrote this code

function testing() {
    console.log("does it show in the console");
}

testing()
setTimeout(()=> testing(), 3000)

on the second file (the "main.js" file) I wrote this code

function testing() {
    console.log("this will override it"); 
} 
  
testing()

The result I got on the console

does it show in the console               script.js:20  
this will override it                     main.js:2
this will override it                     main.js:2

Based on the knowledge I have I expected the function declaration (testing()) in the second file to override the function testing() in the first file because that would have been the result if I wrote both in the same file.

that was my reason for adding the setTimeout function

function testing() {
    console.log("does it show in the console");
}
  
testing()
setTimeout(()=> testing(), 3000)
  
function testing() {
    console.log("this will override it"); 
} 
  
testing()

The result on the console

this will override it                    script.js:27  
this will override it                    script.js:27  
this will override it                    script.js:27  

It wasn't really confused I'd rather say I learnt something new because I tried the same thing with one external JavaScript file and the inline JavaScript script tag
the external JavaScript script.js file

function testing() {
    console.log("does it show in the console");
}
  
testing()  
setTimeout(()=> testing(), 3000)

the inline JavaScript script tag, as you can see the external script tag was also placed at the top here

<script src="script.js"></script>  
<script>  
    function testing() {
        console.log("this will override it");
    }
  
    testing()  
</script>

I got the same result on the console

does it show in the console               script.js:20
this will override it                     index.html:27
this will override it                     index.html:27

I concluded that's probably how the JavaScript engine runs code, if they are in different file.
Here's what deepseek AI said

Why Your Original Code Worked "Weirdly"
Browsers parse scripts sequentially but execute them immediately when encountered.

Your external script's testing() was called before the inline script had a chance to overwrite it.

The console shows historical logs, even if functions are later modified.

This behavior is why experienced developers avoid duplicate function names! Let me know if you'd like to dive deeper into execution contexts. 🚀

I was happy I learnt something new until I decided to play around with the code again
I added both code to the same file again but did something different this time. I placed the first function in a block (curly brackets)

{  
    function testing() {
        console.log("does it show in the console");  
    }
}  
  
testing()
setTimeout(()=> testing(), 3000)
  
function testing() {
    console.log("this will override it");
}
  
testing()  

Here the result I got on the console

does it show in the console              script.js:22
does it show in the console              script.js:22  
does it show in the console              script.js:22

Now that really got me confused (completely). At this point AI didn't give any reasonable explanation, please I need someone to explain what happened in the last code.

Why did the first function in the curly braces print to the console despite declaring (overriding) the same function in the same code?

6
  • 1
    @fdomn-m that doesn't really address the question - which is why the block scoped function behaves the way it does. The proposed duplicate also doesn't touch on block scope and web compat semantics which is what the core of the question is for. It's..."fun". Commented Jun 16 at 13:38
  • When it's in the same file, the function gets hoisted. Do you know about hoisting? Commented Jun 16 at 14:15
  • @MisterJojo there is scope involved in the last piece of code - there is a block scoped function declaration. Yes, that's not good code but it does have semantics that are determined by the presence of a block scope. Removing the block changes how the code behaves. The question is explicitly about the last code block. Commented Jun 16 at 14:38
  • This is two unrelated questions. One regarding code loading in HTML and one about block scoping in javascript. Both are duplicates. Commented Jun 17 at 7:30
  • 1
    A better block scoping duplicate: What are the precise semantics of block-level functions in ES6? and a related question Why is a block-scoped function work outside the scope? (also answered by @Pointy) Commented Jun 17 at 7:36

1 Answer 1

1

First thing: don't do that. JavaScript module systems were developed in part to make "global" scoping more manageable. If you want solid reliable code, use modules and avoid the coding style in this question completely.

Functions at the global scope of an execution unit are hoisted. Function declaration statements inside blocks are "reified" when the block is executed. Thus, in your last example, the "override" version is treated as if the declaration appears at the very top of the execution unit. When executing, the block happens first, and the function declaration inside of it now overrides the hoisted function. All calls to the function happen after the block.

Sign up to request clarification or add additional context in comments.

3 Comments

I'll add that function declaration statements inside blocks (and certainly inside conditional blocks) are an only-recently standardized part of the language, and at best it's an awkward thing to do. Now, function expressions are another thing entirely, as they work like values and not as context-altering declarations.
Block-scoped functions are just...weird in loose mode. Strict mode does make them behave much better. OP's situation is quite rare nowadays as we typically use modules and for most projects have build chains that emit code in strict mode anyway.
thank you, I understand it better now

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.