3

I have the following code in a js file:

var english = { 
  firstname: 'Tony ', 
  lastname:'Smith',
  address: {
    street: "777 guid str",
    city: "New York",
    state: "NY"     
  } 
}; 

var spanish = { 
  firstname: 'Roberto ', 
  lastname:'Tzuark',
  address: {
    street: "227 guid str",
    city: "New York",
    state: "NY"     
  }
};

function greet(person) {
  console.log('hi ' + person.firstname + person.lastname);
}

and the following code in html:

    <form id="myForm" method="get">
    <button type="button" name="english" onClick="greet(english)">english</button>
    <button type="button" name="spanish" onClick="greet(spanish)">spanish</button>
    </form>

When the button is clicked I get an "undefined" error in the console. However, if I change the variable names 'english' and 'spanish' to ANYTHING else, it works fine. These are not listed in the javascript reserved words (http://www.w3schools.com/js/js_reserved.asp)

Why doesn't it work?

Murat Ozgul
  • 11,193
  • 6
  • 29
  • 32
Kadjia
  • 97
  • 5
  • Works fine for me: https://jsfiddle.net/92jLkpz1/ the only change I made is to add all of your variables to window because jsfiddle seems to run in strict mode and prevent globals. – Loïc Faure-Lacroix Jan 05 '16 at 08:46
  • It should work. But to use it in browser globally, I would recommend assigning those variables to `window` object explicitely. – SzybkiSasza Jan 05 '16 at 08:46

2 Answers2

2

You have a button named “english”, which gets put on window. There are two fixes, both of which you should apply:

  1. Don’t name buttons. Unless multiple buttons have the same name and different values, there is no reason to give a button element a name attribute.

  2. Don’t use inline event handlers in your HTML. Attach them separately with JavaScript.

    (function () {
        var english = …;
        var spanish = …;
    
        var englishButton = document.getElementById('english');
        var spanishButton = document.getElementById('spanish');
    
        englishButton.addEventListener('click', function () {
            greet(english);
        });
    
        englishButton.addEventListener('click', function () {
            greet(spanish);
        });
    })();
    <form id="myForm" method="get">
        <button type="button" id="english">english</button>
        <button type="button" id="spanish">spanish</button>
    </form>
    

    … making sure your <script> element is at the end of <body>. The IIFE is there so that your variables aren’t globals, meaning they can’t conflict with properties of window.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • thanks for your help, i just couldn't understand why the specific words created this problem – Kadjia Jan 05 '16 at 14:54
0

That is because those variables get overwritten with global variables derived from the names 'english' and 'spanish' of the DOM elements (buttons). You can just change the names of the buttons not to interfere with your variables, for example:

<form id="myForm" method="get">
    <button type="button" name="english_button" onClick="greet(english)">english</button>
    <button type="button" name="spanish_button" onClick="greet(spanish)">spanish</button>
</form>

You can read about it here:

Do DOM tree elements with ids become global variables?

Community
  • 1
  • 1
n-dru
  • 9,285
  • 2
  • 29
  • 42