有关打字稿编译的问题

时间:2020-01-21 02:07:34

标签: javascript typescript tsc

关于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。为什么私有变量在编译后变成公共变量?

我以为下面的代码将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();

1 个答案:

答案 0 :(得分:1)

为什么私有变量在编译后成为公共变量?

在实例上直接 私有属性的想法是一个非常新的想法(使用#语法)。实际的Javascript中没有privatepublic这样的关键字。可以在Typescript中声明私有或公共属性,以帮助您和其他阅读和使用该代码的人了解该代码的使用意图,但并不能使其成为必需< / em>。

出于类似的原因,您可以写

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. 包装匿名函数的作用是什么?

整个类的创建都封装在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;
}());