构造函数异步操作与原型继承问题:如何绑定异步获取的数组到原型?
解决构造函数异步赋值与原型方法的问题
嗨,我来帮你捋捋这个问题哈~你遇到的this.arr是undefined的情况,主要是两个原因:异步操作的时序问题和回调函数里的this指向错误,我给你一步步拆解并给出解决方案:
问题根源分析
1. 异步操作的时序问题
你在构造函数里调用的Service.getService()是异步请求(通过then就能看出来),当你创建实例后立刻调用example.getArray()时,这个异步请求还没完成,this.arr根本还没被赋值,所以输出undefined是必然的。
2. 回调函数的this指向错误
在then的普通函数回调里,默认的this并不指向Constructor的实例(非严格模式下指向全局对象,严格模式下是undefined),所以你写的this.arr = data.data.array,其实根本没给实例对象添加arr属性。
解决方案
我给你两种常用的解决思路,你可以根据自己的场景选择:
方案一:在实例上挂载Promise,处理异步时序
这个方案会把异步请求的Promise存在实例上,同时修正this指向,让原型方法可以兼容异步完成前后的调用:
function Constructor() { // 用箭头函数继承外层构造函数的this,确保this指向实例 this.servicePromise = Service.getService().then(data => { this.arr = data.data.array; return this.arr; }); } Constructor.prototype.getArray = function() { // 如果arr已经加载完成,直接输出并返回 if (this.arr) { console.log(this.arr); return Promise.resolve(this.arr); } // 如果还没完成,等待Promise后再输出返回 return this.servicePromise.then(arr => { console.log(arr); return arr; }); } // 使用方式 const example = new Constructor(); // 方式1:等待异步完成后调用getArray example.servicePromise.then(() => { example.getArray(); }); // 方式2:直接调用getArray,它会自动处理异步情况 example.getArray();
方案二:用async工厂函数创建实例
如果你的场景允许用工厂函数代替构造函数,这种方式更直观——等异步数据获取完成后,再创建并返回实例,这样实例的arr属性在创建时就已经存在了:
// 定义原型方法 const Constructor = function() {}; Constructor.prototype.getArray = function() { console.log(this.arr); return this.arr; } // async工厂函数处理异步逻辑 async function createExample() { const data = await Service.getService(); // 创建实例并赋值 const example = Object.create(Constructor.prototype); example.arr = data.data.array; return example; } // 使用方式 createExample().then(example => { example.getArray(); // 这里能直接输出正确的arr });
关键要点总结
- 异步操作一定要考虑时序:不能在异步请求完成前就去获取还没赋值的属性;
- 回调函数里的this指向要确保正确:箭头函数、
bind、或者提前存self = this都是常用的修正方式; - 原型方法如果依赖异步数据,最好设计成支持Promise的形式,让调用方可以处理异步场景。
内容的提问来源于stack exchange,提问作者Mat.Now
相关产品推荐
相关产品推荐

