模型对象的普通对象 VS 类实例

fis*_*one 5 javascript prototypal-inheritance typescript angular

在 Angular/TypeScript 中创建模型对象的最佳实践是什么:

  1. 我应该将类型注释与对象表示法一起使用Object吗(对象是 的普通实例)?例如let m: MyModel = { name: 'foo' }

  2. 我应该使用new运算符(对象是相应原型的实例)吗?

  3. 这两种方法应该混合使用吗?(例如,普通对象,当从 接收响应时HttpClient,但new MyModel('foobar')为了方便通过将属性作为构造函数参数传递来创建实例)

这个问题的背景

我是 TypeScript 的新手,和许多其他开发人员一样,我来自流行的面向对象语言,如 Java。

我理解的一个核心概念是 TypeScript 中的类型注释在运行时不起作用。它们对编译器和编辑器的自动完成很重要。基本上它是带有编译时类型检查的 ECMAScript。

当时我不知道这一点,并希望 TypeScript 成为某种“客户端 Java”,我发现了这个 Angular 错误报告:https : //github.com/angular/angular/issues/20770

人们(不理解 TypeScript 的类型概念)抱怨HttpClient没有将返回的普通对象转换为他们的模型类类型。其他人为这种行为辩护并指出 JavaScript 中没有运行时类型。

这里出现了我的问题:事实上,JavaScript 中有运行时类型。您可以使用new运算符创建原型的实例,甚至可以使用运算符检查它们的构造函数instanceof

在 TypeScript 中,您有两种创建实例的方法:

1) 使用对象表示法(如Angular 教程中所示):

hero: Hero = {
  id: 1,
  name: 'Windstorm'
};
Run Code Online (Sandbox Code Playgroud)

2) 使用new-operator:

hero: Hero = new Hero();
Run Code Online (Sandbox Code Playgroud)

目前我正在做一个项目,其中这两个选项混在一起。即相同类型的模型对象Object在某些情况下是 的实例,Hero在其他情况下是 的实例。

我预计这会导致稍后出现问题,因为仅在后一种情况下才会调用构造函数。

我对规则/最佳实践的想法是将所有模型实例定义为普通对象,并将构造函数用于依赖注入创建的服务、组件等。因此,我根本不会使用new运算符。

但是,我不确定这是否是一个好主意,而且我找不到关于它的最佳实践建议。

编辑

给亲密选民的重要说明:我不是在这里寻找您的个人意见。我宁愿寻找某种官方记录的 Angular 最佳实践,因为我认为这是一个核心设计决策,必须从项目开始就做出,这些方法不应该在没有特定原因的情况下随意混合。也许答案只是一个简单的“没有官方建议做出哪个决定”。

Ank*_*rma 3

在我看来,new如果您需要对对象本身执行复杂的操作,您应该使用运算符来创建类的新对象。

如果您只需要访问属性,则可以使用对象文字来创建一个新对象。

它具有封装、继承等优点,对于来自 Java 背景的开发人员来说更能体会到这些优点。

如果像下面这样直接分配一个对象,那么您必须在其中显式设置函数,例如getNamefunction.

hero: Hero = {
  id: 1,
  name: 'Windstorm',
  getName: function(){ // returns name }
};
Run Code Online (Sandbox Code Playgroud)

但是,通过使用Hero函数定义一个类getName,然后创建该类的实例,function无论您创建实例多少次,您都会自动获得该实例。

为了更好地理解面向对象的 Javascript,您可以点击以下链接:-

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS


关于下面的问题,

“人们(不理解 TypeScript 的类型概念)抱怨 HttpClient 没有将返回的普通对象转换为其模型类类型。”

HttpClient只是返回服务器发送的一个对象,由JS将其转换为所需的形式。您始终可以使用其构造函数将响应映射到所需的模型实例,其定义如下:-

constructor(hero){
  this.id = hero.id;
  this.name = hero.name;
}
Run Code Online (Sandbox Code Playgroud)

您可以映射从服务器返回的数组,如下所示:-

map(hero => new Hero(hero))
Run Code Online (Sandbox Code Playgroud)

  • 没有官方文档说明创建对象的最佳实践。然而,这完全取决于开发者和他的背景。使用“类”和“new”运算符可以让应用程序更易于 Java 开发人员理解。事实上,当您可能需要为该对象/模型编写函数时,使用“new”运算符,您可以利用多种可能性,可能同时增强您的应用程序。 (2认同)