javascript - typescript 错误? `this` `get` 语法和 `defineProperty` 的 `get` 之间的差异

标签 javascript typescript this getter defineproperty

我有这个代码:

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 TS 从中生成的内容 @ https://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=22&pc=1#code/G4QwTgBAHhC8EG8oEYBcECsAaaAmdA7AL4DcAUGaJAJ5yJkQQB0LUODEA+gPZgCWAcz4A7EABsAGvihMoudowEBTAC54AFAEoEHRgGNuwgM7cxSpmO4D1KgBZ8js5JvKNGYVQFcwwiAE5XCCIyUjIDY1NzS2tqWVwXCioIAC86HUYWWQUuXkERcSlUGTkQ8gB5ACMAKyU9FSYAEyUAMxElAAUwbgAHJTAVanVknAByORGcBAhlFXRmz2E6vkMtejcIcJMzCysbe0cUBPWPFW9fAI4iIM0wwy2o3eS4hKA .

我的问题有两个:

  1. 鉴于 JS 中的相同代码具有不同的行为,这是否被视为 TypeScript 中的错误?
  2. 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 相同的事情。

首先,您定义一个带有属性 x2y 对象,该属性是一个 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/

相关文章:

javascript - 如何创建一个返回现有 promise 而不是新 promise 的函数?

javascript - 在 Javascript 和服务器中读取第三方 Cookie

javascript - img 通过更改它的 src 并由动态提供的源(mysql 和 php)使用 Javascript 绘制

html - 如何使用 html 中的异步管道获取可观察值的嵌套值

javascript - 有没有办法在使用 ES6 速记方法表示法的方法中包含词法 `this` ?

javascript - 在 IIFE 构造函数中使用 'This'

javascript - react : Convert HOC const to component

javascript - 服务中的 Angular 2 和 rxjs 主题未在组件上更新

typescript - 令人困惑的 "duplicate identifier"Typescript 错误消息

javascript - 将 this 绑定(bind)到高阶函数中的原始对象