如何在JavaScript的fetch函数中访问回调持有者实例的data属性?
问题拆解:为啥原代码拿不到实例?
咱们先把核心问题说透:当你把mycallback.store.bind(mycallback)传给fetch时,你传递的只是一个被绑定了上下文的新函数,不是原fetchCallback实例,也不是原型上的原方法。这个绑定后的函数已经丢失了和mycallback实例的直接关联,所以你尝试的callback.prototype.log.call()、callback.log()这些写法全都会失效——前者找不到正确的原型方法,后者的callback本身根本没有log属性。
几个可行的解决方案
方案1:直接传整个实例(你自己想到的编辑1思路)
这是最省心的方案,既然你要操作实例的方法和属性,那就直接把实例丢给fetch,省得绕弯子:
function fetch(callbackInstance) { const data = [1, 2, 3];// 模拟服务端返回数据 callbackInstance.store(data); callbackInstance.log(); // 直接调用实例的log,this自动绑定为实例本身 } function fetchCallback() { this.data = [] } fetchCallback.prototype.store = function(data) { data.forEach(el => this.data.push(el)); console.log(this.data); } fetchCallback.prototype.log = function() { console.log(this.data); } const mycallback = new fetchCallback(); fetch(mycallback); // 直接传实例就行,不用bind
这个方案逻辑直白,完全避免了this绑定的坑,fetch里想调用实例的啥方法都直接用就行。
方案2:分离回调与数据持有者(你的编辑2思路)
如果想让职责更清晰,把“存储数据”的逻辑和“存数据的容器”分开,这种传回调+持有者的方式也很靠谱:
function fetch(callback, dataHolder) { const data = [1, 2, 3];// 模拟服务端返回数据 callback(data, dataHolder); log(dataHolder.data); } function DataHolder() { this.data = [] } function store(data, holder) { data.forEach(el => holder.data.push(el)); } function log(data) { console.log(data); } const myDataHolder = new DataHolder(); fetch(store, myDataHolder);
这里store函数完全不依赖this,只靠参数拿到数据和容器,彻底避开了上下文绑定的问题,也让函数更“纯”,复用性更强。
方案3:用闭包+函数属性隐式带实例
如果因为某些原因不能修改fetch的参数列表(比如只能传一个回调),那可以给绑定后的函数加个属性,把实例挂上去,让fetch能通过这个属性拿到实例:
function fetch(callback) { const data = [1, 2, 3];// 模拟服务端返回数据 callback(data); // 通过回调上挂载的instance属性获取实例,然后调用log callback.instance.log(); } function fetchCallback() { this.data = [] } fetchCallback.prototype.store = function(data) { data.forEach(el => this.data.push(el)); console.log(this.data); } fetchCallback.prototype.log = function() { console.log(this.data); } const mycallback = new fetchCallback(); // 先绑定上下文,再给绑定后的函数加个instance属性指向原实例 const boundStore = mycallback.store.bind(mycallback); boundStore.instance = mycallback; fetch(boundStore);
这个方案属于“约定式”实现,适合不能改fetch参数的场景,但要注意团队里得统一这个约定,不然别人看代码会懵。
再回头说原代码的坑
最后再给你捋清楚为啥原写法不行:
bind会返回一个全新的函数,这个函数内部把this固定成了mycallback,但它和fetchCallback.prototype.store已经不是同一个函数了。- 你试的
callback.prototype.log.call():绑定后的函数的prototype不是fetchCallback.prototype,根本找不到log方法;就算找到了,你也没传正确的上下文(实例),this会变成undefined(严格模式下)或者全局对象。 callback.log():callback是个普通函数,它本身没有log属性,当然调用失败。
内容的提问来源于stack exchange,提问作者rustyBucketBay
相关产品推荐
相关产品推荐

