我从本地JSON文件中获取了一些设置。函数内的console.log
正确记录对象,但函数返回undefined
后的第二个,所以变量没有更新?
此外,在testNameSpace
内,this
返回window
,为什么?
namespace testNameSpace {
let settings: any;
function dtJSONLoad() {
let xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', './js/file.json', true);
xobj.onreadystatechange = function () {
if (xobj.readyState == 4) {
let response = xobj.responseText;
settings = JSON.parse(response);
console.log(settings);
}
};
xobj.send(null);
}
dtJSONLoad();
console.log(settings);
}
控制台日志' undefined'
控制台日志返回了对象'
答案 0 :(得分:4)
您正面临着SO中最常见的两个问题(至少是那些标有TypeScript
的问题)。
首先是你正在进行异步操作,所以当你这样做时:
dtJSONLoad();
console.log(settings);
console.log
部分正在执行之前 dtJSONLoad
已完成,因此settings
变量未定义。
您的第二个console.log
在异步操作完成时发生,这就是您看到值的原因。
第二个问题是this
的范围:
您正在为xobj.onreadystatechange
属性分配函数,此函数未绑定到当前this
,因此在执行时this
引用Window
对象。<登记/>
你有两个选择:
(1)使用arrow function保存this
的当前范围:
xobj.onreadystatechange = () => {
// ...
};
(2)使用F unction.prototype.bind功能:
xobj.onreadystatechange = function () {
// ...
}.bind(this);
命名空间没有this
,这是因为它被编译成javascript的方式。
例如,这个:
namespace mynamespace {
console.log(this); // Error: 'this' cannot be referenced in a module or namespace body
}
编译成:
var mynamespace;
(function (mynamespace) {
console.log(this);
})(mynamespace || (mynamespace = {}));
这相当于:
function fn() {
console.log(this);
}
在这两种情况下,this
都引用了Window
对象。
如果你这样做:
namespace mynamespace {
export function fn() {
console.log(this);
}
}
mynamespace.fn();
它会打印:Object {}
这是正确的,这是因为fn
功能位于mynamespace
内。
而js的结果如下:
var mynamespace;
(function (mynamespace) {
function fn() {
console.log(this);
}
mynamespace.fn = fn;
})(mynamespace || (mynamespace = {}));
答案 1 :(得分:0)
第一次登录时数据不存在。
第二次是在回调中,当数据到达时,第一次是在请求开始后的第二次。