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

2024-03-04

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

  1. 我应该使用带有对象表示法的类型注释(对象是Object)? E.g. let m: MyModel = { name: 'foo' }

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

  3. 这两种方法是否应该混合使用并根据具体情况使用? (例如普通对象,当收到来自HttpClient, but new MyModel('foobar')为了方便通过将属性作为构造函数参数传递来创建实例)

这个问题的背景

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

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

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

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

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

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

1)使用对象表示法(如它们在角度教程 https://angular.io/tutorial/toh-pt1#create-a-hero-class):

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

2)使用new-操作员:

hero: Hero = new Hero();

目前我正在开发一个混合了这两个选项的项目。 IE。相同类型的模型对象是以下对象的实例Object在某些情况和情况下Hero在其他情况下。

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

我的规则/最佳实践的想法是将所有模型实例定义为普通对象,并使用通过依赖注入创建的服务、组件等的构造函数。结果我不会使用new根本没有操作员。

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

EDIT

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


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

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

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

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

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

然而,通过定义一个类Hero有一个函数getName然后创建该类的实例,您会自动得到function,无论您创建多少次实例。

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

https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS 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;
}

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

map(hero => new Hero(hero))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

普通对象 VS 模型对象的类实例 的相关文章

  • 如何在 Angular 中实现使用 google 登录

    我正在尝试在我的角度应用程序中实现谷歌登录功能 我这里用了两个包 abacritt angularx social login and angular oauth2 oidc 我创建了一个名为的自定义提供程序google authentic
  • 如何通过 HTML 按钮播放声音

    我目前通过网站播放音乐的方法是通过 HTML 音频标签 不过我希望能够通过 HTML 按钮来播放它 该按钮应该能够在播放和停止之间切换音乐 我在 JSFiddle 创建了一个示例 但不知道如何实现它 有人可以告诉我如何使用我的 JSFidd
  • 将 Sweet Alert 弹出窗口添加到 React 组件中的按钮

    我为 Bootstrap 和 React 找到了这个完美的 Sweet Alert 模块 我在 Meteor 应用程序中使用它 http djorg83 github io react bootstrap sweetalert http d
  • 使用模态表单 ajax 超出 HTMLFormElement.toString 的最大调用堆栈大小

    我想使用模态窗口中的 ajax 请求提交表单 单击此链接可打开该模式 a class btn btn primary i class fa fa edit i Write a review a 模态窗口 div class modal fa
  • 保存/导出Chrome的JavaScript控制台输入历史记录

    无论如何 我可以保存或导出 JavaScript 控制台的历史记录吗 input 控制台历史记录 在 Google Chrome 中 我不想保存输出或错误 因此将鼠标悬停在控制台框上 右键单击并选择Save as 不是解决方案 我不想每次都
  • 如何改变HTML5视频的播放速度?

    如何更改 HTML5 中的视频播放速度 我查过视频标签的属性 https www w3schools com html html5 video asp在 w3school 但无法做到这一点 根据这个网站 http www chipwreck
  • v-file-input .click() 不是函数

    我试图以编程方式触发 v file input 的 click 事件 因为它在 Vuetify 的文档中 但它显示一个错误this refs imagePicker click is not a function我在这里错过了什么吗 代码重
  • Angular 2在实例化子组件之前解析根组件

    当我刷新网络应用程序时 我希望它在实例化任何组件或路由之前请求潜在的登录用户数据 如果找到用户的数据 我想将其注入到我的所有其他子组件所依赖的服务中 场景 假设我有 3 个组件 应用程序 ROOT 主页和关于 如果我将此代码放在 About
  • 如何将 Browserify 与外部依赖项一起使用?

    我正在尝试慢慢地将 Browserify 引入我的网站 但我不想重写所有 js 也不希望 jquery 和其他库的重复实例与我的 Browserify 版本捆绑在一起 如果我构建将 jquery 列为外部依赖项的模块 那么如何将其指向我的全
  • 更改离子搜索栏的占位符和清晰图标颜色不是全局的吗?

    我有两个离子搜索栏 我只需要更改其中之一的占位符和清除图标颜色
  • 如何在 e2e AngularJS 测试中进行文件上传?

    在我的一种观点中 我有一个文件上传控件 它支持通过拖放或单击按钮后打开的标准文件对话框上传文件 How to do this in my e2e tests1 1 Just one of the two options will be en
  • 有关于 PHP 中的 V8JS 的文档吗?

    有没有关于V8JS的文档 我是否只需要标准 PHP 或一些扩展即可使用 V8JS 我将非常感谢有关 PHP 中的 V8JS 的任何信息 要求 PHP 5 3 3 和 V8 库和标头安装在正确的路径中 Install http www php
  • Jquery,清除/清空 tbody 元素的所有内容?

    我认为这会相当简单 但似乎空方法无法清除我拥有的 tbody 如果有人知道执行此操作的正确方法 我将不胜感激 我只想删除 tbody 中包含的所有内容 到目前为止我正在尝试 tbodyid empty HTML table tbody tr
  • window.showModalDialog 的等效跨浏览器解决方案是什么?

    window showModalDialog 的等效跨浏览器解决方案有哪些 showModalDialog 在 IE 和 FF 3 中引入 我个人认为没有 但是有很多 UI 工具包提供了这样的功能 例如jQuery UI http jque
  • 从多维无穷大数组中删除数组元素

    我想删除一个特定元素 例如 我想删除元素id 76在下面的数组中 而且 数组可以无限地组合在一起 这里的问题是我无法刷新页面 因为我使用 Vue js 进行即时操作 如果我能做到这一点 我的下一个问题可能是如何在我现在想要的地方添加一个元素
  • Jquery:选择菜单以显示和隐藏某些div元素

    我正在创建一个选择菜单 根据所选选项显示和隐藏某些 div 像这样的东西
  • 加载另一个 JS 脚本后加载

    这是我的代码 very big js file lots of html stuff 问题是 这些是异步加载的 有没有办法等待第二个脚本直到第一个脚本加载 如果您使用 jQuery 有一个非常简单的方法可以通过获取脚本 https api
  • React Native - 跨屏幕传递数据

    我遇到了一些麻烦react native应用程序 我不知道如何跨屏幕传递数据 我意识到还有其他类似的问题在 SO 上得到了回答 但是这些解决方案对我来说不起作用 我正在使用StackNavigator 这是我的设置App js file e
  • 当选择下拉列表中的某些值时,取消选中复选框

    当我从下拉列表中选择某个值或用户未从下拉列表中选择任何值时 我需要取消选中复选框 我现在正在使用 Jquery 这是我现在使用的代码 但它不起作用 Script
  • Restangular - _.contains() 不是一个函数

    如果您最近通过 Bower 更新了 Restangular 它将安装最新的 Lodash 新的 4 0 然而 这是一个问题 因为 Restangular Angular 现在会抛出错误 contains 不是函数 你怎么解决 解决方案非常简

随机推荐