Why can I create two functions with the same JavaScript signature?

35

I am having doubts about a certain issue in Javascript, suppose the following scenario:

function teste() {
  console.log("teste1");
}

function teste() {
  console.log("teste2");
}

teste();

In this case I realized that my method teste() was half overwritten, I do not know if this is really what happens, when we call it the only test2 that is displayed. Now the doubts about it:

  • This is actually the expected behavior when we declare 2 methods with the same name and parameters in js, it will always override and will the last one declared prevail?
  • Is there any explanation for this behavior, if so what is this? explanation?
  • Is there any way to make it generate any errors or something if someone makes this mistake and declares 2 methods with the same name and parameters?
  • If 3 has some way to do it, what to do if the functions are in different js files?
  • asked by anonymous 16.03.2017 / 14:47

    3 answers

    5

    Short answer:

    This is the "normal" JavaScript behavior. The language has advanced and it is now possible to use const to declare constants that can not be overwritten.

    Elongated response:

    From the beginning, JavaScript allows you to overwrite variable names and functions, and even assign values to variables without declaring them, "declaring them" in global scope, which has generated bugs that are difficult to detect.

    In modern versions of JavaScript a lot of this has been fixed and for you the fix is to use const , assigning a variable a function.

    So in ECMAScript 2015 (version 6 of JavaScript) there is const that starts a variable that can not be overwritten without generating a compilation error.

    Your questions:

      
  • This is actually the expected behavior when we declare 2   methods with the same name and parameters in js, it will always   override and will the last one declared prevail?
  •   

    Yes. Unless you use const (which will generate an error if the names are the same). This is normal behavior, just like CSS, the last to be declared pervalece.

      
  • Is there any explanation for this behavior, if so what is this?   explanation?
  •   

    This is how the language was built, a flexible medium ... But it is being strengthened / corrected in the new versions.

      
  • Is there any way to make it generate any errors or something   if someone makes this mistake and declares 2 methods with the same   name and parameters?
  •   

    Yes, using const , the problem is corrected. That is, it gives an error if a variable is overwritten. In this case you can use:

    const teste = function(){
        console.log('teste 1');
    }
    

    and if you then do const teste = outra coisa... the compiler gives error and does not run.

      
  • If 3 has some way to do it, what to do if the functions   are in different js files?
  •   

    In this case you have to encapsulate things. Or you use CJS, AMD, or ES6 modules. There is not yet a universal specification on the part of the language, but there are proposals that are in analysis in this sense. If you use the Babel compiler you can already use these modules.

    So there are two answers:

    With compiled modules you can declare everything in the "global" scope because the module does not share that scope with other files. All variables are encapsulated and the only thing you can export out of the module is via the reserved word exports . An example:

    function teste(){
        console.log(1);
    }
    
    module.exports = teste;
    

    This way teste is not visible to other files.

    Using native JavaScript, where all files share global space:

    Here you have to encapsulate your own things. The concept is identical but you have to use IIFEs to hide the variables of each other.

    For example:

    // ficheiro A
    (function(global) {
      function teste() {
        console.log('teste A');
      }
    
      global.testeA = teste;
    
    })(this);
    
    // ficheiro B
    (function(global) {
      function teste(nr) {
        var res = nr * nr;
        console.log('teste B', res);
      }
      global.testeB = teste;
    
    })(this);
    
    testeA();
    testeB(17);
        
    26.03.2017 / 10:29
    25

    I believe that you have technically already replied "overwritten", but another also needs to understand a function ... () feature, so I will explain a two way behavior to declare a function and then explain it.

    In JavaScript you can do:

    function x() {
    }
    
    x();
    

    And setting the variable:

    x = function() {
    }
    x();
    

    In both cases it will work, however% w_ of% is different from% w_ of%, so if you do this:

    It will work:

    x();
    
    function x() {
    }
    

    It will not work, will accuse as function x() :

    x();
    
    x = function() {
    }
    

    Now the reason, JavaScript, as well as many languages, does a "pre-processing" of some things declared, ie when it does this:

    x();
    
    function x() {
    }
    

    It will occur before the runtime and will leave all functions that have been declared as x = function() ready to use before actually executing, ie when doing this:

    function teste() {
      console.log("teste1");
    }
    
    teste();
    
    function teste() {
      console.log("teste2");
    }
    
    teste();

    See that undefined appears twice.

    Because this occurs

    The browser's "EcmaScript" (JavaScript) engine will render its own way (it is likely that although internally they work similar though they may work differently to achieve the same result), and it will probably only consider the newer function , ie at runtime the first function ...() probably does not exist anymore.

    Even at runtime JavaScript is probably preprocessed , if you look at the following example, even calling teste2 instead of displaying teste() , it will initially display x() :

    function x() {
       console.log("oi");
    }
    
    var a = 10;
    
    window.onload = function() {
         document.getElementById("test").onclick = function() {
             x();
    
             function x() {
                 console.log(++a);
             }
         };
    };
    <button id="test">Teste</button>
      

    Note: The link cited by Virgilo apparently imply that functions with different parameters are supported, but as testing is not possible, see:

    function adiciona(a) {
        console.log("função 1 => ", a);
    }
    function adiciona(b, c) {
        console.log("função 2 => ", b, c);
    }
    
    adiciona(1);
    adiciona(1, 2);

    The example returns:

    função 2 =>  1 undefined
    função 2 =>  1 2
    

    Alternative

    As this response from SOen , a simple example of checking what you want to call would be:

    function foo(a, b, c)
    {
      if (arguments.length == 2) {
        console.log("foo 1");
      } else if (arguments.length == 3) {
        console.log("foo 2");
      }
    }
    
    foo(1, 2);
    foo(1, 2, 3);

    And there are even more complex alternatives to achieve the desired "effect", but I really think this is totally unnecessary, probably at the beginning of languages like you feel some discomfort, but it's not something you really miss so much.

        
    16.03.2017 / 17:28
    7

    Complementing the answers, if you do not want your function to be overwritten, and keep its values, you can create them using const

    const teste = function () {
        console.log("Teste1")
    }
    
    teste()
    
    var teste = function teste() {
        console.log("Teste2")
    }
    
    teste()

    TypeError: const 'test' has already been declared

    Execution Time-70ms

    var teste = function() {
        console.log("Teste1")
    }
    
    teste()
    
    var teste = function() {
        console.log("Teste2")
    }
    
    teste()

    Test1

    Test2

    Execution Time-48ms

        
    21.03.2017 / 12:04