普通对象VS模型对象的类实例 [英] plain objects VS class instances for model objects

查看:116
本文介绍了普通对象VS模型对象的类实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What is the best practice for creating model objects in Angular / TypeScript:

  1. 我应该使用带有对象符号的类型注释(对象是 Object 的普通实例)吗?例如. let m:MyModel = {name:'foo'}

  1. Should I use type annotation with object notation (objects are plain instances of Object)? E.g. let m: MyModel = { name: 'foo' }

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

Should I use the new operator (objects are instances of the respective prototype)?

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

Should these two approaches be mixed up and used situationally? (E.g plain objects, when receiving a response from the HttpClient, but new MyModel('foobar') for convenience to create instances by passing properties as constructor arguments)

此问题的背景

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

Background of this question

I'm new to TypeScript and like many other developers I come from popular object oriented languages like Java.

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

A core concept I understood is that type annotations in TypeScript don't play a role at runtime. They are important for the compiler and for your editor's auto completion. Basically it's ECMAScript with the addition of compile time type checks.

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

At the time I didn't know this and expected TypeScript to be some kind of "client side Java", I found this Angular bug report: https://github.com/angular/angular/issues/20770

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

People (who don't understand TypeScript's type concept) complain about the HttpClient not converting the returned plain object to their model class type. Other people are defending this behavior and point out that there are no runtime types in JavaScript.

这引起了我的问题:实际上,JavaScript中存在运行时类型.您可以使用 new 运算符创建原型实例,甚至可以使用 instanceof 运算符检查原型的构造函数.

And here arises my problem: In fact there ARE runtime types in JavaScript. You can create instances of prototypes with the new operator and even check their constructor with the instanceof operator.

在TypeScript中,您可以通过两种方式创建实例:

In TypeScript you have two ways for creating an instance:

1)使用对象符号(如 Angular中所示教程):

1) Use the object notation (as they show in the Angular tutorial):

hero: Hero = {
  id: 1,
  name: 'Windstorm'
};

2)使用 new -运算符:

hero: Hero = new Hero();

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

At the moment I'm working on a project where these two options are mixed up. I.e. model objects of the same type are instances of Object in some cases and instances of Hero in other cases.

我希望这会在以后导致问题,因为仅在后一种情况下才调用构造函数.

I expect this leading to problems later, because the constructor is only called in the latter case.

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

My idea for a rule / best practice was to define all model instances as plain objects and to use the constructor for services, components etc. that are created by dependency injection. As a result I wouldn't use the new operator at all.

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

However I'm not sure if this is a good idea and I couldn't find a best practice recommendation about it.

编辑

亲密选民的重要注意事项:我不是在这里寻找您的个人选择.我宁愿在寻找某种正式记录的Angular最佳实践,因为我认为这是必须从项目开始就做出的核心设计决策,并且这些方法不应无缘无故地混为一谈.也许答案只是一个简单的没有官方建议可做出决定".

Important note for close voters: I'm not looking for your personal opionion here. I'm rather looking for some kind of officially documented Angular best practice, as I think it's a core design decision that has to be made right from the project start and these approaches should not be mixed up randomly without a specific reason. Maybe the answer is just a simple "There is no official recommendation which decision to make".

推荐答案

我认为,如果您需要在该类上执行复杂的操作,则应该使用 new 运算符创建类的新对象.对象本身.

In my opinion, you should use the new operator to create new objects of your class if you need to perform complex operations on the object itself.

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

If in case you just need to access the properties only, you may use the object literal to create a new object.

这具有诸如封装,继承等优点,而来自Java背景的开发人员可以更好地与之相关.

This has got advantages like encapsulation, inheritance, etc. which a developer coming from the Java background could better relate to.

如果直接分配如下所示的对象,则必须在其中明确设置函数,例如 getName 函数.

If you directly assign an object like below, then you have to explicitly set functions in it, for example, getName function.

hero: Hero = {
  id: 1,
  name: 'Windstorm',
  getName: function(){ // returns name }
};

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

However, by defining a class Hero with a function getName and then creating an instance of that class, you would automatically get that function, no matter how many times you create instances.

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

For a better understanding of Object Oriented Javascript, you may follow the link below:-

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


关于以下问题,


Regarding the below issue,

人们(不了解TypeScript的类型概念)抱怨关于HttpClient不能将返回的普通对象转换为他们的模型类类型."

"People (who don't understand TypeScript's type concept) complain about the HttpClient not converting the returned plain object to their model class type."

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

HttpClient simply returns an object which the server sends, it is on JS to convert it into the required form. You can always map the response into the required model instance by using its constructor which could be defined as below:-

constructor(hero){
  this.id = hero.id;
  this.name = hero.name;
}

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

and you may map the array returned from the server like below:-

map(hero => new Hero(hero))

这篇关于普通对象VS模型对象的类实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆