0

为了从通过 HTTP 作为 JSON 接收的数据正确实例化 Typescript 对象,我正在探索使用for..in循环的可能性,.hasOwnProperty()如下所示:

class User {
    private name: string;
    private age: number;

    constructor(data: JSON) {
        console.log('on constructor\ndata', data);

        for (var key in data) {
            console.log('key:', key);
            if (User.hasOwnProperty(key)) {
                console.log('User has key:', key);
                this[key] = data[key];
            }
        }
    }

    displayInfo(): string{
        return JSON.stringify(this);
    }
}

let button = document.createElement('button');
button.textContent = "Test";
button.onclick = () => {
    try{
        let json = JSON.parse('{"name": "Zorro","age": "24"}');
        let usr = new User(json);
        console.log(usr.displayInfo());
    }catch (error){
        alert(error);
    }

}

document.body.appendChild(button);

在我的项目中使用类似的代码完全失败。这是意料之中的,因为编译后的 JS 代码不知道私有 TS 变量,所以hasOwnProperty总是false.

但是,我使用的是Typescript Playground,在那里运行该代码会在控制台中产生以下输出:

on constructor
data Object {name: "Zorro", age: "24"}
key: name
User has key: name
key: age
{"name":"Zorro"}

如您所见,这里显然发生了一些意想不到的事情。第一个键被识别,新的 User 实例使用 JSON 中的值初始化,但第二个键不会发生这种情况。

有人可以解释为什么会这样吗?

4

2 回答 2

2

正如评论中指出的那样,您应该使用this.hasOwnProperty而不是User.hasOwnProperty. 正如您所注意到的,这段代码无论如何都被破坏了,因为类中的属性声明实际上并没有在对象上创建自己的属性(它们需要被初始化才能发生)。

但是为什么你会被击中name键呢?该User对象是您的类的构造函数。函数确实有一个name属性:

function fn() { }
console.log(fn.name); // prints 'fn'

当然,他们没有age财产。

于 2016-09-07T18:00:14.143 回答
0

如果你想从普通的 JavaScript 对象构造 User 实例,你的构造函数当然只需要看起来像这样:

constructor(data: any) {
    this.name = data.name;
    this.age = data.age;
}
于 2016-09-07T18:12:31.013 回答