Vue3 forEach内调用方法报Cannot read properties of undefined错误
问题描述
调用宝可梦公开接口https://pokeapi.co/api/v2/pokemon?limit=151拉取初代151只宝可梦列表数据后,期望通过自定义方法_getPokemonData对返回结果做二次处理,映射得到每只宝可梦的完整数据。编写Vue逻辑时出现报错:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '_getPokemonData')
报错触发场景为forEach遍历回调内部调用_getPokemonData方法时,问题复现代码如下:
mounted() { this.$http .get("https://pokeapi.co/api/v2/pokemon?limit=151") .then((response) => { //this.pokemons = response.data.results; this.pokemons = response.data.results.forEach(function(pokemon){ this._getPokemonData(pokemon); }); }); this.$http .get("https://pokeapi.co/api/v2/type/") .then((response) => { this.types = response.data.results; }); }, methods: { _getPokemonData(pokemon) { console.log(pokemon); },
问题原因
this指向错误:forEach传入的是普通function声明的回调,普通函数的this在运行时动态绑定,此处回调执行时处于严格模式,this值为undefined,自然找不到挂载在Vue组件实例上的_getPokemonData方法。- 方法使用错误:
forEach本身没有返回值,将其执行结果赋值给this.pokemons最终只能得到undefined,无法存储处理后的宝可梦数据。
修复方案
- 方案1(推荐):使用箭头函数作为遍历回调,箭头函数不会生成独立的
this上下文,会直接继承外层作用域(即Vue组件实例)的this指向;同时替换forEach为map,收集_getPokemonData处理后的返回值生成新数组赋值给this.pokemons:
mounted() { this.$http .get("https://pokeapi.co/api/v2/pokemon?limit=151") .then((response) => { this.pokemons = response.data.results.map((pokemon) => { return this._getPokemonData(pokemon); }); }); this.$http .get("https://pokeapi.co/api/v2/type/") .then((response) => { this.types = response.data.results; }); }, methods: { _getPokemonData(pokemon) { // 补充宝可梦完整数据处理逻辑 console.log(pokemon); return pokemon; }, }
- 方案2:提前缓存Vue实例引用,在普通回调函数内通过缓存的引用调用实例方法:
.then((response) => { const vm = this; // 遍历前提前存储当前Vue实例 this.pokemons = response.data.results.map(function(pokemon){ return vm._getPokemonData(pokemon); }); });
- 方案3:利用数组遍历方法的第二个参数,显式指定回调执行时的
this指向为当前Vue实例:
.then((response) => { this.pokemons = response.data.results.map(function(pokemon){ return this._getPokemonData(pokemon); }, this); // 传入第二个参数绑定回调的this为当前Vue实例 });
内容的提问来源于stack exchange,提问作者TodMcfRle
相关产品推荐
相关产品推荐

