Angular6 Service构造函数初始化属性报错:私有属性未定义
解决Angular 6 Service中数组初始化报错的问题
嘿,我来帮你搞定这个困扰!你遇到的ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'push' of undefined错误,核心原因其实很直白——你只声明了mockIncident这个数组变量的类型,但从来没给它初始化一个空数组,它默认是undefined状态,自然没法调用push方法啦。
先分析你之前的问题代码
不管是第一种还是第二种写法,都犯了同一个基础错误:
- 第一种:
private mockIncident: Incident[];只是告诉TypeScript这个变量是Incident数组类型,但实际它的值是undefined,调用push肯定报错。 - 第二种:改成
public并新增init方法,但同样没给mockIncident赋值为空数组,而且你的for循环条件还写错了(for(let i = 0; this.mockIncidentRaw.length; i++)会导致无限循环,因为this.mockIncidentRaw.length是一个非零数字,永远为true)。
正确的解决方案
方案1:声明时直接初始化数组(最直观)
在声明mockIncident的时候,直接赋值为空数组,之后再用push填充内容:
private mockIncident: Incident[] = []; // 关键:初始化空数组 constructor() { this.mockIncidentRaw.forEach(incident => { this.mockIncident.push(new Incident().deserialize(incident)) }); }
方案2:用map方法直接生成数组(更优雅)
如果你的需求是把mockIncidentRaw里的每个元素转换成Incident对象,完全可以用map方法直接生成目标数组,连显式初始化空数组都可以省(不过还是建议保持显式初始化的习惯,代码更清晰):
private mockIncident: Incident[] = []; constructor() { this.mockIncident = this.mockIncidentRaw.map(incident => new Incident().deserialize(incident)); }
方案3:修正你的init方法写法
如果你坚持要用单独的init方法,需要同时修正数组初始化和循环条件两个问题:
public mockIncident: Incident[] = []; // 初始化空数组 constructor() { this.init(); } init = () => { // 循环条件修正为 i < this.mockIncidentRaw.length for(let i = 0; i < this.mockIncidentRaw.length; i++) { this.mockIncident.push(new Incident().deserialize(this.mockIncidentRaw[i])) } }
核心要点总结
- 数组类型的变量,声明后一定要先初始化为
[],才能调用push、pop等数组方法 - 写
for循环时,务必检查循环终止条件,避免出现无限循环的问题 - 处理数组转换时,
map方法比forEach+push的组合更简洁高效
内容的提问来源于stack exchange,提问作者NeitoFR
相关产品推荐
相关产品推荐

