TypeScript构造函数语法疑问:手动赋值为何触发类属性不存在报错?
为什么手动赋值构造函数参数会报错?
这事儿的核心在于你没搞清楚TypeScript里参数属性语法和普通构造函数参数的区别,我给你拆解清楚:
首先,constructor(private _weatherService: WeatherService){}这种写法是TypeScript提供的语法糖,它一口气帮你做了三件事:
- 在类的级别声明了一个私有属性
_weatherService - 定义了构造函数的入参
_weatherService - 自动执行
this._weatherService = _weatherService完成赋值
而你手动写的代码没覆盖这些步骤,所以才会出现各种报错,咱们逐个看你的问题:
1. 直接写_weatherService = _weatherService报错
你写的代码是这样的:
constructor(_weatherService: WeatherService){ _weatherService = _weatherService; }
这里的问题有两个:
- 你只是在构造函数里定义了一个局部参数,根本没在类里声明
_weatherService这个属性,类的作用域里完全没有这个变量 - 你写的赋值是把局部参数自己赋值给自己,和类属性半毛钱关系都没有,所以
ngOnInit里访问this._weatherService时,TypeScript自然会说“这个属性不存在”
2. 用private修饰构造函数参数正常运行
这就是参数属性语法的功劳了——TypeScript看到你给构造函数参数加了private(或者public/protected)修饰符,就会自动帮你在类里创建对应的私有属性,并且完成赋值。相当于TypeScript帮你把手动声明和赋值的代码都写了,所以Angular能正常注入服务,你也能在组件里访问这个属性。
3. 写this._weatherService = _weatherService报错
这个报错的原因很直接:你还没在类里声明_weatherService这个属性,TypeScript是强类型语言,类的所有属性必须先声明才能通过this访问。编译器不知道this._weatherService是什么,所以直接报错。
正确的手动写法示例
如果你不想用参数属性语法,手动写的话必须先声明类属性,再赋值:
import { Component, OnInit } from '@angular/core'; import { WeatherService } from './weather.service'; @Component({ selector: 'app-weather-list', templateUrl: './weather-list.component.html' }) export class WeatherListComponent implements OnInit { // 第一步:先在类里声明私有属性 private _weatherService: WeatherService; constructor(_weatherService: WeatherService) { // 第二步:用this把构造函数参数赋值给类属性 this._weatherService = _weatherService; } ngOnInit(): void { // 现在就能正常访问了 this._weatherService.getWeatherData().subscribe(data => { // 处理数据 }); } }
简单总结:参数属性语法就是TypeScript帮你偷懒的语法糖,Angular里依赖注入的时候几乎都会用它,既简洁又不容易写错。
内容的提问来源于stack exchange,提问作者user3760959
相关产品推荐
相关产品推荐

