简体   繁体   中英

Variable 'name' doesn't return undefined

I'm learning about hoisting in JavaScript. When I try this code

console.log('name', name)
console.log('age', age)
console.log('occupation', occupation)

var name = 'tom'
var age = '23'
var occupation = 'builder'

in my developer tools in chrome i get

name tom
age undefined
occupation undefined

how come name is not undefined but other variables are?

Edit:

My html file

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src = "index.js"></script>
</body>
</html>

My index.js file

console.log('name', name)
console.log('age', age)
console.log('occupation', occupation)

var name = 'tom'
var age = '23'
var occupation = 'builder'

I restarted my computer, created new files and nothing has changed. In firefox I get

name <empty string> 
age undefined 
occupation undefined

This is working exactly as it's supposed to: the declarations ( but not assigned values ) for "age" and "occupation" are hoisted, so your console log shows them existing with value "undefined" (rather than throwing a ReferenceError ), but name is special: you're not the one who declared it, even though your code makes it look like you are:

What's really going on is that the code you've written is scoped, and so when you say var name = "tom" , what you've actually written is currentscope.name = "tom" . In any kind of explicit scope (a function, a module, etc) this will behave the way you expected, but in global scope in a browser (or more precisely, "in any execution context in which your scope is window "), what this means is that your code actually executes as window.name = "tom" .

And so that's where things go wrong: name already exists as a global property on the window object

Of course, this goes for any other value too, if you var numbats = "cute"; in global scope, that's the same as window.numbats = "cute"; so if you don't want to run into silent naming conflicts: don't declare things in global scope. Test this in a function (where var name will shadow the global name ), or you can use modern JS and use let instead of a curly bracket block but of course then we're not using var anymore.

Fun little known fact: setting the global name to "tom" and then browsing the web for an hour in the same tab will, even an hour later, still have window.name be your value, unless someone else has changed it, which almost never happens. It's one of those hilarious ways in which multi-faceted tracking stays possible.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM