javascript / 打字稿中的构造函数和新对象

时间:2021-02-14 18:10:52

标签: javascript typescript function

我有一项任务是创建一个构造函数来创建一个计算面积和周长的 Circle 对象。

到目前为止,我得到了下面的代码,但不明白为什么 this 有下划线,而 new Circle(3) 有下划线。

我尝试更改 function Circle(this:any, radius: number) { 以删除带下划线的 this,但我不明白为什么带下划线的 new Circle 无法修复。

function Circle(radius: number) {
    const pi = 3.14;
    this.radius = radius;
    this.area = function () {
        return pi * radius * radius
    }
    this.perimeter = function () {
        return 2 * pi * radius;
    }
}
// pi * r kv
//2pi*r
const c = new Circle(3);
console.log("Area =", c.area().toFixed(2)); // Expected output: Area = 28.27
console.log("Perimeter =", c.perimeter().toFixed(2)); // Expected output: Perimeter = 18.85

2 个答案:

答案 0 :(得分:1)

假设这是在一个 TypeScript 文件中(而不是一个 JavaScript file checked with TypeScript),那么根据 microsoft/TypeScript#2310,这是明确不支持的。如果您想要 TypeScript 中的类构造函数,强烈建议您使用 class 语法。如果 function 是 ES5 或更低版本,它将被降级为 --target,因此您不必担心。如果您使用 class 语法,this 上下文和 new 将正常工作:

class Circle {

  radius: number;
  area: () => number;
  perimeter: () => number;

  constructor(radius: number) {
    const pi = 3.14;
    this.radius = radius;
    this.area = function () {
      return pi * radius * radius
    }
    this.perimeter = function () {
      return 2 * pi * radius;
    }
  }

}

const c = new Circle(3); // okay

(通常我希望方法在原型上而不是在实例上,但我主要是不理会你的实现)。


如果你真的需要在 TypeScript 中支持函数作为构造函数,你必须使用 type assertions 来告诉编译器你知道你在做什么:

interface Circle {
  radius: number;
  area: () => number;
  perimeter: () => number;
}

interface CircleConstructor {
  new(radius: number): Circle;
}

const Circle = function Circle(this: Circle, radius: number) {
  const pi = 3.14;
  this.radius = radius;
  this.area = function () {
    return pi * radius * radius
  }
  this.perimeter = function () {
    return 2 * pi * radius;
  }
} as any as CircleConstructor;
    
const c = new Circle(3); // okay

在上面我已经为 Circle 实例类型和 CircleConstructor 构造函数类型显式定义了接口:如果您使用 class 语法,这些类型会自动发生,其中类型将分别命名为 Circletypeof Circle。然后需要将 Circle 函数断言为 CircleConstructor 类型,以便 new Circle(3) 调用起作用。此外,我给函数签名一个 this parameter,它在运行时不存在,但用于告诉编译器它应该在实现中考虑 this 的类型。我说 this: Circle 是为了让编译器知道在 Circle 函数内部,它可以访问 this 属性,就好像 thisCircle 实例一样。

因此,这与 class 版本的工作方式或多或少相同,只是您必须跳过不必要的圈子才能执行此操作,并且启动的类型安全性较低。所以除非你这样做是为了某种魔术(看着我只用一根牙签从这个密封的箱子里出来)我强烈建议你使用 class 语法,并拒绝任何问你的人在 TypeScript 中做其他事情。

Playground link to code

答案 1 :(得分:0)

希望我了解您的需求。 您可以使用 Class 而不是使用 Function。 这是您想要的简单解决方案。

class Circle { 
   radius:number; 
   pi = 3.14;
   constructor(radius:number) { 
      this.radius = radius;
   }  

   area():number { 
      return this.pi * this.radius * this.radius;
   } 
   perimeter():number { 
      return 2 * this.pi * this.radius;
   } 
}

var c = new Circle(3);
console.log('Area = '+c.area().toFixed(2));
console.log('Area = '+c.perimeter().toFixed(2));

它不会抛出任何错误并遵循所有标准程序。 祝你好运。

相关问题