TypeScript - 命名空间/范围变量更新

时间:2016-08-25 15:17:12

标签: javascript json typescript

我从本地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'

控制台日志返回了对象'

2 个答案:

答案 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)

第一次登录时数据不存在。

第二次是在回调中,当数据到达时,第一次是在请求开始后的第二次。