模块模式中工厂函数创建对象无法访问内部数组的原因咨询
为什么工厂函数创建的对象无法访问模块内的变量?
你遇到的问题核心是**JavaScript词法作用域(Lexical Scope)**的限制,具体拆解如下:
问题代码复现
const createPlayer = (name) => { let properties = { name, copyArr(){ let newArr = gameArr; console.log(newArr) } } return properties // 注:原代码存在笔误,此处应返回properties而非未定义的player } const game = (() => { const gameArr = [1,2,3,4,5] let player = createPlayer("Fred") let testObj = { name: "Bob", copyArr(){ let newArr = gameArr; console.log(newArr); } } testObj.copyArr(); // 正常输出[1,2,3,4,5] player.copyArr(); // 报错:gameArr is not defined return })()
根本原因
JavaScript的函数作用域是词法作用域——函数能访问的变量,只取决于它被定义时所在的作用域,和调用时的环境无关:
createPlayer定义在全局作用域,它内部的copyArr方法在创建时,作用域链只能覆盖全局作用域和createPlayer自身的作用域,完全接触不到game模块内部的私有变量gameArr。哪怕后续player对象是在game模块里被实例化的,调用copyArr时依然会沿着定义时的作用域链找变量,自然找不到gameArr。testObj是直接在game模块内部定义的,它的copyArr方法在创建时就处于game的作用域内,作用域链包含了game模块的私有作用域,所以能直接访问到gameArr。
你提到的两种解决方法的合理性
- 把createPlayer放入game模块中:此时
createPlayer的词法作用域包含了game模块的作用域,内部的copyArr方法自然能访问到gameArr,完全符合词法作用域的规则。 - 给copyArr添加gameArr参数:通过显式传参的方式,把
gameArr从game模块传递给copyArr,相当于绕开了作用域的限制,让方法能拿到需要的变量。
内容的提问来源于stack exchange,提问作者kayzed
相关产品推荐
相关产品推荐

