You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对象方法中For loop失效求助:记忆小游戏数组生成失败

问题根源:对象方法里的this指向跑偏了!

嘿,这个问题我太懂了——你遇到的情况几乎可以肯定是**this的上下文指向不对**导致的!

为什么会这样?

在JavaScript的对象方法里,this的指向不是固定的,它完全取决于你怎么调用这个方法:

  • 如果直接调用对象的方法(比如myGame.generateCards()),this会正确指向你的游戏对象;
  • 但如果把这个方法当作回调函数传给其他东西(比如setTimeout、事件监听器addEventListener),或者用某种方式间接调用,this就会变成全局对象(浏览器里是window),在严格模式下甚至会变成undefined。

这时候你在for循环里用this.pairCount(或者你用来控制循环次数的属性),拿到的就是undefined,循环条件i < undefined不成立,自然就不会执行,最后返回空数组。

而你换成普通变量的时候,变量是在全局作用域或者外层函数作用域里,不受this指向的影响,所以循环能正常跑起来。

举个直观的例子对比

错误场景(this指向错误):

const MemoryGame = {
  pairCount: 3,
  generateCards() {
    let cards = [];
    // 这里的this如果不是指向MemoryGame,this.pairCount就是undefined
    for (let i = 0; i < this.pairCount; i++) {
      cards.push(i, i);
    }
    return cards;
  }
};

// 直接调用没问题
console.log(MemoryGame.generateCards()); // [0,0,1,1,2,2]

// 但作为定时器回调调用,this指向window,返回空数组
setTimeout(MemoryGame.generateCards, 1000); // 输出 []

正常场景(普通变量不受this影响):

let pairCount = 3;
function generateCards() {
  let cards = [];
  for (let i = 0; i < pairCount; i++) {
    cards.push(i, i);
  }
  return cards;
}

// 不管怎么调用都正常
setTimeout(generateCards, 1000); // 输出 [0,0,1,1,2,2]

解决方法有这几种,选适合你的就行:

  • 方法1:用箭头函数定义方法
    箭头函数会继承外层上下文的this,不会被调用方式改变:

    const MemoryGame = {
      pairCount: 3,
      generateCards: () => {
        let cards = [];
        for (let i = 0; i < this.pairCount; i++) {
          cards.push(i, i);
        }
        return cards;
      }
    };
    
  • 方法2:在方法内部先保存正确的this
    把对象的this存到一个变量(比如self或者that)里,循环里用这个变量代替this:

    const MemoryGame = {
      pairCount: 3,
      generateCards() {
        const self = this; // 保存正确的this指向
        let cards = [];
        for (let i = 0; i < self.pairCount; i++) {
          cards.push(i, i);
        }
        return cards;
      }
    };
    
  • 方法3:调用方法时用bind绑定this
    如果你需要把方法作为回调,可以用bind强制绑定对象的this:

    setTimeout(MemoryGame.generateCards.bind(MemoryGame), 1000);
    
  • 方法4:用Class来组织你的游戏代码
    Class里的方法默认会绑定到实例,只要你不是把方法裸传给回调(可以用箭头函数包裹):

    class MemoryGame {
      constructor() {
        this.pairCount = 3;
      }
      generateCards() {
        let cards = [];
        for (let i = 0; i < this.pairCount; i++) {
          cards.push(i, i);
        }
        return cards;
      }
    }
    
    const game = new MemoryGame();
    // 用箭头函数包裹回调,确保this指向game实例
    setTimeout(() => console.log(game.generateCards()), 1000);
    

最后检查一下

你可以在方法的开头加个console.log(this),看看输出的是什么——如果不是你的游戏对象,那就是this指向的问题没错了!

内容的提问来源于stack exchange,提问作者Martz89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:50:05