1

I have an HTML file test.html where I have two variables both named location, one global and one local. But when I open it in browser it just says Your file was not found, and the address bar shows file://Los%20Angeles instead of file://test.html as expected. Why?

<html>
<body>
<script type="text/javascript">
var location = "Los Angeles"
function showLocation() {
    var location = "San Francisco"
    document.write(location)
}
</script>
<input type="button" onclick="showLocation()" value="Show Location"/>
</body>
</html>
Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Zhaowei Wu
  • 115
  • 2
  • 8

2 Answers2

2

'location' is a reserved keyword in javascript. Just change your variable name into something else. For more info about reserved words: https://www.w3schools.com/js/js_reserved.asp

Kavindra
  • 1,697
  • 2
  • 14
  • 19
  • 1
    Also since you've declared a variable outside a scope (global variable) if your goal is to modify the value, all you have to do is to just call the variable inside your function and just assign a new value to it, no need to declare it again. – jek Sep 04 '17 at 01:54
  • @jhek thanks. I was just trying to test the result of using the same name to declare a global var and a local var. – Zhaowei Wu Sep 04 '17 at 01:57
  • Thank you! I never thought about reserved keyword : ) – Zhaowei Wu Sep 04 '17 at 02:00
  • This answer is still the wrong one: `location` is not a reserved word at all. Changing the variable name is the least safe and least future-proof approach, because it doesn’t avoid the fundamental issue. If a new standard introduces another clashing property name, you’d have to rename again, forever. Instead, using [JavaScript modules](//developer.mozilla.org/en/docs/Web/JavaScript/Guide/Modules) is the safest and most future-proof approach, because modules have their own scope and their own lexical environment; no clashes are possible there. – Sebastian Simon Dec 19 '22 at 23:30
2

Setting the global location causes the browser to go to that URL. It’s not a reserved word1 — it’s a property defined on the global object (globalThis, which is window in the Web).

In your example, you are setting the global location to "Los Angeles", which causes the browser to navigate to that as if it was a relative URL.

Setting var location = "San Francisco" inside your function has no effect on the window object because the running execution context inside a function has its own variable environment, which is different from the one in global scope.

So you could do this:

function showLocation() {
    var location = "San Francisco";
    
    document.write(location)
}

and it will work as expected. It will write the string "San Francisco" to the document.

If you are on a modern browser, you can see what’s going on by trying so set 'location' with 'let':

let location = "los angeles";

Now you will get an error that says something like:

SyntaxError: Can’t create duplicate variable that shadows a global property: 'location'.


1: If you want to know what the reserved words are in JavaScript, take a look at the MDN documentation.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
Mark
  • 90,562
  • 7
  • 108
  • 148
  • The current best practice to avoid this issue is to use [JavaScript modules](//developer.mozilla.org/en/docs/Web/JavaScript/Guide/Modules), which have their own scope, and their own variable environment (or more precisely LexicalEnvironment). I’ve written [an answer](/a/51062916/4642212) to a related question that provides a complete list of variables that behave similarly. It’s not too easy to characterize these variables, but it’s basically non-configurable `Window.prototype` (and other) properties with setters. – Sebastian Simon Dec 19 '22 at 23:26