为什么这个变量在没有var的情况下保存而不是全局的?

时间:2011-10-27 15:17:15

标签: javascript scope google-chrome-extension

这个问题与I asked yesterday类似的javascript范围问题有关。我希望你能帮我解决这个问题。

我正在使用Chrome扩展程序。 options.html将新用户电子邮件另存为localStorage“用户”,并在refreshUser()中调用background.html功能:

//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”。问题是newUserrefreshUser()内更新,但在null之外refreshUser()

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

function refreshUser () 
{
    newUser = localStorage.getItem("user");
    console.log("newUser inside of refreshUser function " + newUser);
    //newUser is updated with saved email in localStorage
}

console.log("newUser after refreshUser() " + newUser);
//newUser=null

newUser为什么refreshUser()在没有var关键字的情况下定义为background.html?谢谢你的帮助!

更新

在回复pimvdb's answer时,我复制了newUser的代码。如果我想在formData中使用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> 内调用哪个函数?感谢。

background.html

更新回复pimvdb's comment

我遇到的问题是在浏览器打开时加载options.html,但之后电子邮件会保存在refreshUser()中。因此background.html告诉newUser从localStorage获取formData.append("extension_user", newUser); 。然后我需要在formData中使用“newUser”,如下所示:

refreshUser()

但我现在拥有它的方式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? 之外的“newUser”为空。我错过了什么?

更新以澄清为什么某些日志未在控制台中显示

这就是我的所作所为:

{{1}}

4 个答案:

答案 0 :(得分:2)

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

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

你的措辞“newUser after refreshUser()”之后是相当暧昧的。它确实在声明之后执行,但newUser根本没有改变,因此两个日志都在函数日志null之外。您尚未设置尚未设置的内容时无法访问它。

以下内容应该记录正确,因为全局变量已更新。只需在中将其设置为{em>,然后在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();
}

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

我认为之前的答案是相关的: What is the scope of variables in JavaScript?

尝试在全局上下文中使用var声明变量。

答案 3 :(得分:1)

我只是想评论一下定义变量的做法,但是评论的时间太长了。

您不希望在没有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