为啥在 Angular 2 的构造函数中编写初始化逻辑不是一个好习惯

Posted

技术标签:

【中文标题】为啥在 Angular 2 的构造函数中编写初始化逻辑不是一个好习惯【英文标题】:Why is it not a good practice to write initialization logic in the constructor in angular 2为什么在 Angular 2 的构造函数中编写初始化逻辑不是一个好习惯 【发布时间】:2020-03-13 03:13:08 【问题描述】:

为什么我们只在OnInit()方法中编写初始化逻辑而不在构造方法中编写?使用构造函数方法进行初始化的所有副作用是什么?请解释。

【问题讨论】:

【参考方案1】:

构造函数中未处理的错误将转义调用堆栈,并强制堆栈帧向上跳转调用堆栈到第一个错误处理程序。当前调用堆栈上仍在构造的任何父组件也将崩溃。

@Component(..)
export class ExampleComponent implements OnDestroy 
   public constructor() 
      throw new Error("I crash the app!");
   

   public ngOnDestroy() 
      console.error('I am never executed!');
   

OnInit() 方法发生在 Angular 渲染循环的摘要循环中,并且独立于父组件调用。此处未处理的错误只会逃逸当前组件的摘要,而父组件将继续工作而不会中断。

@Component(..)
export class ExampleComponent implements OnInit, OnDestroy 
   public ngOnInit() 
      throw new Error("I crash gracefully!");
   

   public ngOnDestroy() 
      console.log('I am still executed!');
   

发生错误的地方会对组件的生命周期产生影响。如果ngOnInit 发生错误,ngOnDestroy 方法将继续工作,但如果构造函数发生错误,则组件完全丢失。

【讨论】:

【参考方案2】:

来自 Angular 文档 (found here):

使用 ngOnInit() 有两个主要原因:

在构造后不久执行复杂的初始化。 在 Angular 设置输入属性之后设置组件。 经验丰富的开发人员一致认为组件应该便宜且构建起来安全。

不要在组件构造函数中获取数据。您不必担心新组件在测试中创建时或在您决定显示它之前会尝试联系远程服务器。构造函数应该只将初始局部变量设置为简单值。

ngOnInit() 是组件获取其初始数据的好地方。

Mike Hevery(Angular 团队负责人)的一篇文章说更多 here

构造函数用于创建类,而 onInit 用于构建组件本身。虽然我自己从未经历过这种情况,但显然构造函数中资源可能无法完全可用

这个article,虽然有点简单,但还有很多要说的,但不是Angular官方文档

根据我的经验,尽管我将构造函数代码保持在最低限度,但我从未遇到过代码无法运行或导致问题的问题,因为它位于构造函数中而不是 onInit 方法中。

【讨论】:

以上是关于为啥在 Angular 2 的构造函数中编写初始化逻辑不是一个好习惯的主要内容,如果未能解决你的问题,请参考以下文章

为啥我应该在构造函数而不是 ngOnInit 中创建我的 Angular2 响应式表单?

为啥编译器在尝试使用 C++11 样式初始化对象数组时隐式删除​​构造函数

错误 C2512:没有适当的默认构造函数可用 - 为啥在构造函数中初始化属性?

我应该在其构造函数中还是在 app.component 的 ngOnInit 方法中初始化 Angular 服务?

在 Jest 测试框架中访问 Angular 服务构造函数

为啥类的常量数据成员需要在构造函数中初始化?