TypeScript中含未定义对象引用的数组赋值为何仍为undefined?
问题原因分析与解决方案
核心误解:JavaScript的"引用传递"不是你想的那样
JavaScript里的变量传递是按值传递——当变量存储的是对象引用时,传递的是这个引用的副本,而不是变量本身的"动态链接"。你的代码问题出在执行顺序和引用存储的时机上。
代码执行过程拆解
- 当你执行:
此时this.myField = new InputField(...) .withRevalidateOtherFields([this.otherField]);this.otherField还未被赋值,它的值是undefined。这个undefined被放进数组,作为参数传给withRevalidateOtherFields,最终被赋值给myField的otherFieldsForRevalidation私有字段。 - 之后执行
this.otherField = new InputField(...);,只是给this.otherField这个变量重新赋值了一个新的对象引用,但之前数组里存储的undefined不会被同步更新——数组里存的是当时的undefined值,和现在this.otherField的新引用毫无关联。
解决方案
方案1:调整初始化顺序(最直接)
先完成this.otherField的初始化,再调用withRevalidateOtherFields:
this.otherField = new InputField(...); this.myField = new InputField(...) .withRevalidateOtherFields([this.otherField]); console.log(this.myField.otherFieldsForRevalidation); // [InputField实例]
如果觉得链式调用被打断不够优雅,可以拆分写法,但逻辑更清晰。
方案2:用懒加载延迟获取引用(适合无法调整顺序的场景)
修改InputField类,让otherFieldsForRevalidation存储返回目标字段的函数,而不是直接存储字段值,这样每次需要使用时都能获取最新的引用:
class InputField { private otherFieldsForRevalidation: (() => InputField)[] = []; public withRevalidateOtherFields(getFields: (() => InputField)[]): this { this.otherFieldsForRevalidation = getFields; return this; } // 示例:使用时调用函数获取最新字段 public getRevalidationFields(): InputField[] { return this.otherFieldsForRevalidation.map(getter => getter()); } } // 调用方式 this.myField = new InputField(...) .withRevalidateOtherFields([() => this.otherField]); this.otherField = new InputField(...); console.log(this.myField.getRevalidationFields()); // [InputField实例]
内容的提问来源于stack exchange,提问作者Maxim
相关产品推荐
相关产品推荐

