Javascript TypeScript-命名空间/范围变量更新
我正在从本地JSON文件获取一些设置。函数中的Javascript TypeScript-命名空间/范围变量更新,javascript,json,typescript,Javascript,Json,Typescript,我正在从本地JSON文件获取一些设置。函数中的console.log正确记录对象,但函数返回undefined后的第二个日志,因此变量没有被更新 另外,在testNameSpace中,此返回窗口,为什么 namespace testNameSpace { let settings: any; function dtJSONLoad() { let xobj = new XMLHttpRequest(); xobj.overrideMimeTyp
console.log
正确记录对象,但函数返回undefined
后的第二个日志,因此变量没有被更新
另外,在testNameSpace
中,此
返回窗口
,为什么
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);
}
控制台日志“未定义”
控制台记录返回的对象“第一次记录时数据不在那里
第二次是在回调中,当数据到达时,第一次是在请求启动后的第二次。第一次记录数据时,数据不在那里
第二次是在回调中,当数据到达时,第一次是在请求开始后的第二次。在SO中,您面临两个最常见的问题(至少是标记为
TypeScript
的问题)
首先,您正在进行异步操作,因此在执行此操作时:
dtJSONLoad();
console.log(settings);
console.log
部分在dtJSONLoad
完成之前执行,因此settings
变量未定义。第二个
console.log
发生在异步操作完成时,这就是您看到该值的原因
第二个问题是本的范围:您正在为
xobj.onreadystatechange
属性分配一个函数,此函数不绑定到当前this
,因此执行时this
将引用窗口
对象。这里有两个选项: (1) 使用保存此的当前范围的:
xobj.onreadystatechange = () => {
// ...
};
(2) 使用F函数:
xobj.onreadystatechange = function () {
// ...
}.bind(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);
}
在这两种情况下,此
都引用了窗口
对象
但是,如果您这样做:
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 = {}));
在SO中,您面临着两个最常见的问题(至少是标记为
TypeScript
的问题)
首先,您正在进行异步操作,因此在执行此操作时:
dtJSONLoad();
console.log(settings);
console.log
部分在dtJSONLoad
完成之前执行,因此settings
变量未定义。第二个
console.log
发生在异步操作完成时,这就是您看到该值的原因
第二个问题是本的范围:您正在为
xobj.onreadystatechange
属性分配一个函数,此函数不绑定到当前this
,因此执行时this
将引用窗口
对象。这里有两个选项: (1) 使用保存此的当前范围的:
xobj.onreadystatechange = () => {
// ...
};
(2) 使用F函数:
xobj.onreadystatechange = function () {
// ...
}.bind(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);
}
在这两种情况下,此
都引用了窗口
对象
但是,如果您这样做:
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 = {}));
我明白你的意思,但事实并非如此。如果在函数之后注释掉console.log,则对象返回。如果我注释掉函数中的一个,则只返回undefined。不过,我不知道他们为什么要按那个顺序登录。这正是我所说的@PaulRedmond。请在你的日志中添加一些字符串来识别它们。我知道你在说什么,但事实并非如此。如果在函数之后注释掉console.log,则对象返回。如果我注释掉函数中的一个,则只返回undefined。不过,我不知道他们为什么要按那个顺序登录。这正是我所说的@PaulRedmond。请在日志中添加一些字符串来识别它们。看起来你是对的,这与异步有关。如果设置为false,则会正确更新。看起来您是对的,这与异步有关。如果设置为false,则会正确更新。对,我明白你的意思。当I
console.log(这个)时
在namespace testNameSpace
中,它也返回window
,这是为什么?检查我修改过的答案,我明白你的意思了。当Iconsole.log(这个)时
在名称空间testNameSpace
中,它也会返回窗口
,为什么会这样?检查我修改过的答案