Javascript 为什么在函数中保存此变量时不使用var而不是全局变量?

Javascript 为什么在函数中保存此变量时不使用var而不是全局变量?,javascript,scope,google-chrome-extension,Javascript,Scope,Google Chrome Extension,这个问题是关于一个类似的javascript作用域问题。我希望你能帮我解决这个问题 我正在使用Chrome扩展options.html将新用户电子邮件保存为“user”并调用refreshUser()后台.html中的函数localStorage: //save entered gmail address document.getElementById("save").addEventListener( "click", function () { var use

这个问题是关于一个类似的javascript作用域问题。我希望你能帮我解决这个问题

我正在使用Chrome扩展
options.html
将新用户电子邮件保存为“user”并调用
refreshUser()
后台.html中的函数
localStorage

//save entered gmail address
document.getElementById("save").addEventListener(
    "click", function ()
    {
        var user = document.getElementById("getEmail").value;
        localStorage.setItem("user", user);
        chrome.extension.getBackgroundPage().refreshUser();
    } , false)
然后我在
background.html
中将电子邮件保存为“newUser”。问题是
newUser
refreshUser()
内部更新,但在
refreshUser()
外部更新为
null

为什么
newUser
是本地的
refreshUser()
,而它的定义没有
var
关键字?谢谢你的帮助

更新

作为响应,我复制了我的
background.html
的代码。如果我想在
formData
中使用
newUser
,我需要在
refreshUser()中调用哪个函数?谢谢

<html>
<script>

newUser = localStorage.getItem("user");
console.log("first newUser " + newUser);

function refreshUser () 
{
    newUser = localStorage.getItem("user");
    console.log("newUser inside of refreshUser function " + newUser);
}

console.log("newUser after refreshUser() " + newUser);

//I want to user newUser below in formData  
chrome.browserAction.onClicked.addListener(function(tab) 
{
    chrome.tabs.getSelected(null, 
    function(tab) 
    {
        // Send a request to the content script.
        chrome.tabs.sendRequest(tab.id, {action: "getDOM"}, 
        function(response) 
        {
            var firstParagraph = response.dom;

            var formData = new FormData();
            formData.append("url", tab.url);
            formData.append("title", tab.title);
            formData.append("pitch", firstParagraph);
            formData.append("extension_user", "abc@gmail.com");
            //I want to user newUser here:
            //formData.append("extension_user", newUser);
            console.log("newUser inside formData: " + newUser)

            var xhr = new XMLHttpRequest();
            xhr.open("POST", "http://ting-1.appspot.com/submithandlertest", true);
            xhr.onreadystatechange = 
            function (aEvt) 
            {
                if (xhr.readyState == 4) 
                {
                    if (xhr.status == 200)
                    { 
                        console.log("request 200-OK");
                        chrome.browserAction.setBadgeText ( { text: "done" } );
                        setTimeout(function () 
                        {
                            chrome.browserAction.setBadgeText( { text: "" } );
                        }, 2000);
                    }
                    else
                    {
                        console.log("connection error");
                        chrome.browserAction.setBadgeText ( { text: "ERR" } );
                    }        
                }        
            };
            xhr.send(formData);
        }); //chrome.tabs.sendRequest
    });
});


</script>
</html>
但是我现在在
refreshUser()
之外的“newUser”是空的。我错过了什么

更新以澄清某些日志未显示在控制台中的原因

我就是这么做的:

1. I reload the extension and start with localStorage empty
2. I use the extension to save a bookmark
3. all 3 logs are null as expected

 first newUser null
 newUser after refreshUser() null
 newUser inside formData: null
 request 200-ok

4. now I save user email in options as abc@gmail.com
5. now I use the extension again to save a bookmark
6. now refreshUser is executed and the log inside the function says abc@gmail.com and formData log says abc@gmail.com

newUser inside of refreshUser function abc@gmail.com
newUser inside formData: abc@gmail.com
request 200-OK

7. but what confuses me is that now the first 2 logs do not show in the console. Why?

它是全球性的,但你在错误的时间访问它

函数refreshUser(){…}
只是一个函数声明;没有什么是真正执行的。声明之外的两个日志立即运行,此时未设置
localStorage
项(即
null

您的措辞“刷新用户()后的新用户”相当含糊不清。它确实是在声明之后执行的,但是
newUser
根本没有被更改,因此这两个日志都在函数日志
null
之外。您无法在它尚未设置时访问它,这与您的预期相符

由于全局变量已经更新,下面的日志应该可以很好地记录。只需在
refreshUser
中设置后调用它即可

function otherFunction() {
    // logs the global variable 'newUser', which is thus indeed global
    console.log("newUser inside otherFunction: " + newUser);
}

function refreshUser () 
{
    newUser = localStorage.getItem("user");
    otherFunction();
}

它是全球性的,但你在错误的时间访问它

函数refreshUser(){…}
只是一个函数声明;没有什么是真正执行的。声明之外的两个日志立即运行,此时未设置
localStorage
项(即
null

您的措辞“刷新用户()后的新用户”相当含糊不清。它确实是在声明之后执行的,但是
newUser
根本没有被更改,因此这两个日志都在函数日志
null
之外。您无法在它尚未设置时访问它,这与您的预期相符

由于全局变量已经更新,下面的日志应该可以很好地记录。只需在
refreshUser
中设置后调用它即可

function otherFunction() {
    // logs the global variable 'newUser', which is thus indeed global
    console.log("newUser inside otherFunction: " + newUser);
}

function refreshUser () 
{
    newUser = localStorage.getItem("user");
    otherFunction();
}

您尚未在发布的代码段中调用refreshUser(),因此不会对其进行设置


尝试调用它,然后检查全局newUser。

您在发布的代码段中没有调用refreshUser(),因此不会设置它


试着调用它,然后检查全局新用户。

我只想对定义变量的实践进行评论,但是评论太长了

如果没有
var
关键字,您永远不会想要定义新变量,它会 导致各种各样的欺骗和意想不到的结果。如果你愿意 要确保它是全局变量,请使用全局对象

var globalObject = this,
    globalVariable = 1; //or globalObject.globalVariable = 1;

function example(){
var globalVariable;

globalVariable = 2 //This will not set the global variable and you can see it's not intended either since we used var
console.log( globalObject.globalVariable ); 
globalObject.globalVariable = 2 // This will set the global variable, the intent to do so is very explicitly shown
console.log( globalObject.globalVariable ); 
}

example();
//1
//2
console.log( globalObject.globalVariable, globalVariable );
//2 2

我只是想评论一下定义变量的实践,但是评论太长了

如果没有
var
关键字,您永远不会想要定义新变量,它会 导致各种各样的欺骗和意想不到的结果。如果你愿意 要确保它是全局变量,请使用全局对象

var globalObject = this,
    globalVariable = 1; //or globalObject.globalVariable = 1;

function example(){
var globalVariable;

globalVariable = 2 //This will not set the global variable and you can see it's not intended either since we used var
console.log( globalObject.globalVariable ); 
globalObject.globalVariable = 2 // This will set the global variable, the intent to do so is very explicitly shown
console.log( globalObject.globalVariable ); 
}

example();
//1
//2
console.log( globalObject.globalVariable, globalVariable );
//2 2

谢谢你的回答。由于
background.html
中有嵌套函数,我不确定需要从
refreshUser
调用什么
otherFunction()
。我用
background.html
更新了我的问题,你能帮助我从
refreshUser()调用函数吗?再次感谢。@Zeynel:您不需要
otherFunction
;这更像是一个“证据”,证明它是全球性的。我不确定你想调用什么函数。您现在所拥有的应该可以工作,尽管
refreshUser
做的不多。执行
refreshUser
时,您希望发生什么?您想再次执行xhr部分吗?好的,您是对的,现在它可以工作了,当
refreshUser
被选项调用时,
formData
中的
newUser
页面将用新保存的电子邮件更新。但是我仍然不明白为什么在执行
refreshUser
时前两个日志不显示。您的回答解决了问题,谢谢,但是在理解程序流程方面,您能帮助解释为什么前两个日志没有显示吗?我用我正在尝试做的事情更新了这个问题。再次感谢。@Zeynel:这两个函数(
first newUser
newUser after refreshUser()
)不在任何函数中。它们会在脚本加载后立即显示,但不再显示。第一次保存书签时,您将看到前两个日志,因为它们是在加载脚本时记录的。它们与使用扩展保存书签无关(即,它们不会因为交互而运行)。谢谢您的帮助,现在我明白了。谢谢您的回答。由于
background.html
中有嵌套函数,我不确定需要从
refreshUser
调用什么
otherFunction()
。我用
background.html
更新了我的问题,你能帮助我从
refreshUser()调用函数吗?再次感谢。@Zeynel:您不需要
otherFunction
;这更像是一个“证据”,证明它是全球性的。我不确定你想调用什么函数。您现在所拥有的应该可以工作,尽管
refreshUser
做的不多。当
刷新用户时,您希望发生什么<