TypeScript手册:类静态端示例过度复杂

时间:2015-10-01 12:57:59

标签: typescript

见过"foo"部分http://www.typescriptlang.org/Handbook#classes-advanced-techniques

中的示例
Classes -> Advanced Techniques

并解释:

  

接下来,我们直接使用该类。在这里,我们创建一个名为'greeterMaker'的新变量。这个变量将保存类本身,或者说其构造函数的另一种方式。这里我们使用'typeof Greeter',即“给我Greeter类本身的类型”而不是实例类型。或者,更确切地说,“给我一个名为Greeter的符号的类型”,这是构造函数的类型。此类型将包含Greeter的所有静态成员以及创建Greeter类实例的构造函数。我们通过在'greeterMaker'上使用'new'来创建这个,创建'Greeter'的新实例并像以前一样调用它们。

我的问题:引入class Greeter { static standardGreeting = "Hello, there"; greeting: string; greet() { if (this.greeting) { return "Hello, " + this.greeting; } else { return Greeter.standardGreeting; } } } var greeter1: Greeter; greeter1 = new Greeter(); alert(greeter1.greet()); var greeterMaker: typeof Greeter = Greeter; greeterMaker.standardGreeting = "Hey there!"; var greeter2:Greeter = new greeterMaker(); alert(greeter2.greet()); 变量的目的是什么?最终,它只包含对greeterMaker类的引用。

我们可以在下面编写代码,

Greeter

得到相同的结果,不要把我们与奇怪的看起来混淆

Greeter.standardGreeting = "Hey there!";
var greeter2:Greeter = new Greeter();
alert(greeter2.greet());

我在这里遗漏了什么吗? 构造var greeterMaker: typeof Greeter = Greeter; 确实有用吗?

2 个答案:

答案 0 :(得分:0)

我认为你的代码是正确和简单的,但他们采取了中间步骤,在操作之前先将Greeter类型分配给变量。

解析那行代码,他们只是说:

var greeterMaker // there is a variable named greeterMaker
                : typeof Greeter // the static type of this variable is a constructor function for the Greeter class;
                                 = Greeter; // Assign the value of Greeter (the constructor function) to the variable greeterMaker

最后,greeterMakerGreeter是一回事。 (因为代码正在执行var greeterMaker = Greeter;

我只能假设他们的例子是这样做的,只是为了证明你可以分配"类型的类型"作为变量的静态类型。 换句话说,var greeterMaker: typeof Greeter;表示greeterMaker的静态类型是Greeter的构造函数,而不是Greeter的实例,这是示例的值。

答案 1 :(得分:0)

我对这个确切的例子感到困惑了好几个小时。在示例中,他们希望显示使用new Greeter()实例化类和使用typeof Greeter之间的区别。令人困惑的部分是他们跟着

let greeter2: Greeter = new greeterMaker();
这会跳过/隐藏差异。暂时忽略greeter2行并仅关注下面的代码,因为这是可以看到差异的地方。

let greeter1: Greeter = new Greeter(); // var greeter1 = new Greeter();

let greeterMaker: typeof Greeter = Greeter; // var greeterMaker = Greeter;

如果您记录greeter1和greeterMaker,那么该示例是有意义的,因为您可以看到差异:new Greeter()是对象类Greeter typeof Greeter是类Greeter 构造函数

console.log(greeter1); // Greeter{} <-- the greeter object

console.log(greeterMaker);
// function Greeter() {} <-- class Greeter's constructor function
// console.log(Greeter) results in the same: function Greeter(){}

在greeter1日志中可以看到Greeter{}对象(可以在控制台中展开以显示所有类成员),这可能仍然令人困惑。

Greeter {}
    └─  __proto__: Object
        ├─  constructor: Greeter()
        ├─  greet: ()
        └─  __proto__: Object

但是greeterMaker控制台日志仅显示构造函数的JavaScript代码

function Greeter() {
}  

如果您查看示例上方的段落(来自此问题中的链接),它开始有意义。

  

在这里,&#39; var Greeter&#39; (在这种情况下&#39; var greeter1&#39;) 将被分配构造函数。当我们打电话给新的&#39;并且运行此函数,我们得到一个类的实例。

因此,我们在登录greeter1时看到控制台中的完整对象(构造函数已经运行并且实例已创建,而{{ 1}}只向我们展示了构造函数,为了创建Greeter类的实例,它仍然必须被调用才能运行。

现在回到

greeterMaker

let greeter2: Greeter = new greeterMaker(); console.log(greeter2.greet()); 一样,我们无法直接致电Greeter() - 我们会收到错误

greeterMaker().greet()

console.log(greeterMaker().greet()); // Value of type 'typeof Greeter' is not callable. Did you mean to include 'new'? console.log(Greeter().greet()); // Value of type 'typeof Greeter' is not callable. Did you mean to include 'new'? Greeter()引用了在没有调用&#34; new&#34;的情况下无法访问的构造函数。因此,示例显示您可以使用greeterMaker()实例化类,或使用new Greeter()创建类的副本,然后可以使用typeof Greeter调用该类。

我意识到这是一个很老的帖子,但我遇到了这个问题,并且我认为如果有人需要关于这个例子的更多信息,我可以对此有所了解。干杯