构造函数中设置的变量不可见及Player列表显示技术咨询
问题解答
问题1:构造函数中设置的变量无法被访问
这种情况通常有几个常见原因,我给你逐一分析并给出解决办法:
变量未在类中显式声明:如果你的类里没提前定义要赋值的变量,直接在构造函数里用
this.xxx = ...,虽然JS会自动给实例添加这个属性,但TypeScript会报错,或者外部访问时会有类型问题。解决办法是在类顶部先声明变量:class YourClass { // 先声明变量类型 targetVar: string; constructor() { this.targetVar = "赋值内容"; } }访问修饰符限制:如果变量被声明为
private或protected,那类外部是无法直接访问的。如果需要外部访问,要么改成public(默认就是public,可省略),要么添加getter方法:class YourClass { private _targetVar: string; constructor() { this._targetVar = "赋值内容"; } // 提供getter让外部访问 get targetVar() { return this._targetVar; } }this指向错误:如果构造函数里的回调函数(比如定时器、异步操作)中使用
this,很可能会丢失正确的指向。解决办法是用箭头函数绑定this,或者手动bind:class YourClass { targetVar: string; constructor() { this.targetVar = "赋值内容"; // 箭头函数自动绑定当前this setTimeout(() => { console.log(this.targetVar); // 能正常访问 }, 1000); } }
问题2:区分Player与SpecialPlayer实例并显示类型
先看你代码里的小问题:SpecialPlayer构造函数里的thi...应该是拼写错误,应该是this.mode = "SpecialPlayer"。我先给你修正完整的类代码,再讲怎么在列表里正确区分显示:
修正后的类定义
export class Player { name: string; mode: string; // 建议把name作为构造参数传入,方便实例化 constructor(name: string) { this.mode = "Player"; this.name = name; } } export class SpecialPlayer extends Player { constructor(name: string) { super(name); // 调用父类构造函数 this.mode = "SpecialPlayer"; // 覆盖父类的mode值 } }
列表中区分显示的两种方法
直接使用mode属性:只要子类正确覆盖了
mode,遍历列表时直接读取player.mode就能拿到对应的类型标识:// 假设players是从后端获取的实例数组 const playerList = players.map(player => { return `${player.name} - ${player.mode}`; }); // 渲染playerList即可,会显示类似"张三 - Player"、"李四 - SpecialPlayer"的内容用instanceof判断类型:如果担心
mode属性被意外修改,或者需要做更多类型专属逻辑,可以用instanceof判断:const playerList = players.map(player => { let type = "Player"; if (player instanceof SpecialPlayer) { type = "SpecialPlayer"; } return `${player.name} - ${type}`; });
注意:后端数据的转换问题
如果后端返回的是JSON格式的数据,直接解析后并不是类的实例(JSON会丢失原型链),这时候需要手动把JSON数据转换成对应的类实例:
// 假设从后端拿到的原始数据 const rawData = [ { name: "普通玩家", mode: "Player" }, { name: "特殊玩家", mode: "SpecialPlayer" } ]; // 转换为类实例数组 const players: (Player | SpecialPlayer)[] = rawData.map(item => { if (item.mode === "SpecialPlayer") { return new SpecialPlayer(item.name); } else { return new Player(item.name); } });
内容的提问来源于stack exchange,提问作者julienduchow
相关产品推荐
相关产品推荐

