打字稿错误? `get` 语法和 `defineProperty` 的 `get` 之间的区别
TypeScript bug? `this` difference between `get` syntax and `defineProperty`'s `get`
我有这个代码:
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 中 运行 this as 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 在作为第二个或更多参数传递的对象中时被调用 [= =19=]。当 getter 被调用时, this
引用第二个参数,这里的这个对象:
{
_originalX2: x.x2,
get x2() {
console.log(this.x1);
}
}
它没有 x1
属性,因此它记录 undefined
。
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');
}
};
我有这个代码:
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 中 运行 this as 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 在作为第二个或更多参数传递的对象中时被调用 [= =19=]。当 getter 被调用时, this
引用第二个参数,这里的这个对象:
{
_originalX2: x.x2,
get x2() {
console.log(this.x1);
}
}
它没有 x1
属性,因此它记录 undefined
。
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');
}
};