我有以下脚本:
<script>
var xmlhttp = new XMLHttpRequest();
var myApp = angular.module("myApp", []);
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
response = this.responseText;
var myObj = JSON.parse(response);
console.log(myObj);
}
};
xmlhttp.open("GET", "functions.php?action=getuserdata&id=" + document.getElementById('userID').innerHTML, true);
xmlhttp.send();
console.log(myObj);
myApp.controller("myCtrl", function ($scope) {
$scope.firstName = myObj[0].firstname;
$scope.lastName = myObj[0].lastname;
$scope.email = myObj[0].email;
$scope.cell = myObj[0].cell;
$scope.domainname = myObj[0].domainname;
$scope.tfamethod = myObj[0].tfamethod;
$scope.said = myObj[0].said;
});
</script>
现在我的理解是&#39; var&#39;关键字,全局分配一个可从窗口内的任何位置访问的变量。我在onreadystatechange函数中设置了var,并且在执行第一个console.log时我能够看到它,但我得到的是&#39; undefined&#39;当我在功能外再次登录时。我对var的理解不正确吗?如果是这样,我如何修复代码以便能够从函数外部访问myObj?
答案 0 :(得分:3)
该代码有两个问题:
var
现在我的理解是'var'关键字,全局分配一个可从窗口内的任何位置访问的变量。
这种理解是不正确的。 var
在var
出现的函数中声明一个变量。要声明一个全局变量,请在所有函数之外声明它。
或者更好,不要。浏览器上的全局命名空间非常拥挤。相反,将所有代码包装在作用域函数中并将“全局变量”放在那里。它们可以被所有代码访问,而不是实际上是全局的。
另外:您不能在代码中使用myObj
,因为它不会被分配,无论它在何处声明。有关原因,请参阅this question's answers。
所以这是带有作用域函数的代码,并在正确的位置使用myObj
(在回调中);此外,由于您只使用返回数组中的第一个条目,因此您可以访问该条目一次而不是重复:
(function() {
var xmlhttp = new XMLHttpRequest();
var myApp = angular.module("myApp", []);
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
response = this.responseText;
var myObj = JSON.parse(response)[0]; // Note the [0]
myApp.controller("myCtrl", function($scope) {
$scope.firstName = myObj.firstname;
$scope.lastName = myObj.lastname;
$scope.email = myObj.email;
$scope.cell = myObj.cell;
$scope.domainname = myObj.domainname;
$scope.tfamethod = myObj.tfamethod;
$scope.said = myObj.said;
});
}
};
xmlhttp.open("GET", "functions.php?action=getuserdata&id=" + document.getElementById('userID').innerHTML, true);
xmlhttp.send();
})();
答案 1 :(得分:0)
用var声明的变量的范围是它的当前执行上下文,它是封闭函数,或者对于在任何函数外部声明的变量,是全局的。
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var
因此,如果在函数内部声明变量,则无法在此函数外部访问它。
固定代码:
var myObj;
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
response = this.responseText;
myObj = JSON.parse(response);
console.log(myObj);
}
};
xmlhttp.open("GET", "functions.php?action=getuserdata&id=" + document.getElementById('userID').innerHTML, true);
xmlhttp.send();
console.log(myObj);
答案 2 :(得分:0)
用var定义的变量具有功能上下文。它们首先在功能上提升,仅可从功能体上获得。如果要从外部访问变量,首先在外部定义并访问函数内部。只有未定义的变量才具有全局范围。
答案 3 :(得分:0)
我认为您需要了解变量范围的工作原理。 MDN做得很好解释
但长话短说。如果你想创建一个糟糕的“全局”变量,它将与你的第二个console.log()
所以这段代码会被重构为。
//Global variable
var myObj;
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
response = this.responseText;
myObj = JSON.parse(response);
console.log(myObj);
}
};
xmlhttp.open("GET", "functions.php?action=getuserdata&id=" + document.getElementById('userID').innerHTML, true);
xmlhttp.send();
// Probably will log incorrectly because of the timing,
// This code is ran before the callback of the XHR, because the
// javascript interpreter wont wait for that callback to finish before
// interpreting additional code (Which is good cause then the UI
// doesn't pause while the request is being performed
console.log(myObj);
我会再给你一个例子
var foo = 1;
function log(){
var bar = 2
baz = 4
console.log(foo); // 1
console.log(bar) // 2
console.log(baz) // 3
}
console.log(foo); // 1
console.log(bar) // undefined
console.log(baz) // 3
另外我注意到你正在使用angularJS,但是你正在编写超级详细的XHR请求,我建议你查看HTTP服务。