这个问题与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”。问题是newUser
在refreshUser()
内更新,但在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}}
答案 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