关于打字稿编译的问题

Questions about typescript compile

我有两个关于 ts 的问题。

未编译代码

class K {
  private p = 3;
  public q = 4;
  public r = () => {
    console.log(this.p, this.q);
  };
}

new K().r();

编译代码

var K = /** @class */ (function() {
  function K() {
    var _this = this;
    this.p = 3;
    this.q = 4;
    this.r = function() {
      console.log(_this.p, _this.q);
    };
  }
  return K;
})();
new K().r();

1。为什么编译后私有变量变成public?

我认为代码会像下面这样将 q 设为私有。为什么TS不做?

var K = /** @class */ (function() {
  var p = 3;
  function K() {
    var _this = this;
    this.q = 4;
    this.r = function() {
      console.log(p, _this.q);
    };
  }
  return K;
})();
new K().r();

2。包裹匿名函数有什么作用?

如果不使用模块模式,匿名函数好像没什么用。我认为代码可能如下所示。

var K = function() {
  var _this = this;
  this.p = 3;
  this.q = 4;
  this.r = function() {
    console.log(_this.p, _this.q);
  };
};
new K().r();

Why private variables become public after compilation?

私有属性 直接 在实例上的想法是一个非常新的想法(使用 # 语法)。实际Javascript中没有privatepublic这样的关键字。在 Typescript 中声明 属性 private 或 public 是为了 帮助您和其他阅读和使用代码的人 理解代码的用途,但是它并没有使它成为 必需的.

出于类似的原因,你可以这样写

window.fn = (arg: string) => {
  console.log(arg.slice(5));
};

然后,在项目之外,在 Javascript 中写入

window.fn(5);

尽管 fn 只接受字符串。

如果你想让属性实际上无法从外部访问,请使用#,例如:

class K {
  #p = 3;

此语法在 Javascript 中非常新,并且仅在 Typescript 3.8+ 中受支持。例如

class K {
  #p = 3;
  public q = 4;
  public r = () => {
    console.log(this.#p, this.q);
  };
}

new K().r();

编译为

"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
    if (!privateMap.has(receiver)) {
        throw new TypeError("attempted to get private field on non-instance");
    }
    return privateMap.get(receiver);
};
var _p;
var K = /** @class */ (function () {
    function K() {
        var _this = this;
        _p.set(this, 3);
        this.q = 4;
        this.r = function () {
            console.log(__classPrivateFieldGet(_this, _p), _this.q);
        };
    }
    return K;
}());
_p = new WeakMap();
new K().r();
  1. What is the role of wrapping anonymous function?

class 的整个创建都封装在一个 IIFE 中。有时,这似乎没有任何作用,但对于某些类型的转译代码,它有助于防止不必要的范围泄漏。例如

class K {
  #p = 3;
  static foo = 'bar'
  method() {

  }
}

转译为

"use strict";
var K = /** @class */ (function () {
    function K() {
        _p.set(this, 3);
    }
    K.prototype.method = function () {
    };
    var _p;
    _p = new WeakMap();
    K.foo = 'bar';
    return K;
}());