我有这个代码:
var x = {
x1: 5,
x2: 7
};
var y = {
...x,
_originalX2: x.x2,
get x2() {
console.log(this.x1);
return 9;
}
};
console.log(y.x2);
var z = {
...x,
_originalX2: x.x2
};
Object.defineProperty(z, 'x2', {
get: function() {
console.log(this.x1);
return 9;
}
})
console.log(z.x2);
当我在浏览器或 NodeJS 中将其作为 JavaScript 运行时,我得到输出:
5
9
5
9
当我运行与 TypeScript 相同的代码时(请参阅 https://repl.it/repls/TornHomelyThing ),我得到输出:
undefined
9
5
9
我的问题有两个:
- 鉴于 JS 中的相同代码具有不同的行为,这是否被视为 TypeScript 中的错误?
this
无法在 TypeScript 生成的 JS 中引用x1
是否有充分的理由?或者,这是 JS 本身的错误吗?
最佳答案
Is this to be considered a bug in TypeScript given that the same code in JS has different behavior?
是的,这看起来确实像是与 Typescript 的对象扩展语法转换相关的错误。编译后的 TS 并没有做与 JS 相同的事情。
首先,您定义一个带有属性 x2
的 y
对象,该属性是一个 getter:
var y = {
...x,
_originalX2:x.x2,
get x2(){
因此稍后引用 y.x2
会导致调用 getter。但在编译后的 Typescript 中,我们得到:
var x = { x1: 5, x2: 7 };
var y = Object.assign(
Object.assign({}, x),
{
_originalX2: x.x2,
get x2() {
console.log(this.x1);
}
}
);
这将导致 getter 被立即调用 - getter 在作为 Object.assign
内的第二个或更多参数传递的对象中时被调用。当调用 getter 时,this
引用第二个参数,这里的 this 对象:
{
_originalX2: x.x2,
get x2() {
console.log(this.x1);
}
}
它没有 x1
属性,因此它记录 undefined
。
在 Object.assign
完成之前,在到达 console.log( 的下一行之前, 会记录
.未定义
y.x2);
一个更简单的例子:
var y = {
...{},
get prop(){
console.log('should not be invoked immediately');
}
};
被错误地转译为
var y = Object.assign({}, { get prop() {
console.log('should not be invoked immediately');
} });
如果你让 Typescript 不转译对象扩展语法,通过将目标提升到 ES2017 之后,它就会起作用。例如,使用 ESNext,上面的内容会被转换为:
var y = {
...{},
get prop() {
console.log('should not be invoked immediately');
}
};
关于javascript - typescript 错误? `this` `get` 语法和 `defineProperty` 的 `get` 之间的差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60861329/