Google Apps Script类模式异常:依赖注入执行问题求助
Google Apps Script 类依赖注入失败问题排查与修复
核心问题
你的代码问题与Google V8引擎、.gs文件结构无关,纯粹是TocSheet构造函数的参数顺序不匹配,导致注入的依赖被分配到了错误的变量中:
- 在
UiManager.gs的start函数里,你调用new TocSheet(spreadsheetApp, propsService),传递了两个依赖对象 - 但
TocSheet.gs的构造函数定义是constructor(name, titles, spreadsheetApp, propsService),前两个参数是可选的name和titles - 这就导致:
spreadsheetApp被赋值给了name参数,propsService被赋值给了titles参数,而真正需要依赖的spreadsheetApp和propsService参数拿到的是undefined,最终触发了默认值逻辑,重新实例化了SpreadsheetUtility,这就是你日志里看到的现象。
修复方案
方案1:调整构造函数参数顺序(把依赖参数放在最前面)
修改TocSheet.gs的构造函数,将必填的依赖参数放在可选参数之前:
class TocSheet { constructor(spreadsheetApp, propsService, name, titles){ console.log("From Toc: Spreadsheet: ", spreadsheetApp, propsService) this.state = {}; this.state.name = name || "Table of Contents"; this.spreadsheetApp = spreadsheetApp || new SpreadsheetUtility(); this.propsService = propsService || new PropertiesServiceStorage(); this.state.properties = { sheetId: null, titles: null, range:{ headerName: "TOCHeader", tocName: "TOC" }} this.initialize(); } // 其他方法保持不变 }
调用时保持原有代码即可:
const myToc = new TocSheet(spreadsheetApp, propsService);
方案2:使用对象解构传递参数(更推荐,彻底避免顺序问题)
修改TocSheet.gs的构造函数为对象参数形式,这样参数顺序不再重要:
class TocSheet { constructor({spreadsheetApp, propsService, name, titles} = {}){ console.log("From Toc: Spreadsheet: ", spreadsheetApp, propsService) this.state = {}; this.state.name = name || "Table of Contents"; this.spreadsheetApp = spreadsheetApp || new SpreadsheetUtility(); this.propsService = propsService || new PropertiesServiceStorage(); this.state.properties = { sheetId: null, titles: null, range:{ headerName: "TOCHeader", tocName: "TOC" }} this.initialize(); } // 其他方法保持不变 }
调用时传递对象参数:
const myToc = new TocSheet({spreadsheetApp, propsService});
额外潜在bug修复
除了核心问题,代码里还有几个小问题需要修正:
- TocSheet.setTitles方法错误:
原代码中title.getSheetId() !== this.sheetId里的this.sheetId未定义,应该改为this.state.properties.sheetId:setTitles(titles = null){ if(titles){ this.state.properties.titles = titles }else{ const sheets = this.spreadsheetApp.getSheets(); const titles = sheets.filter(title => title.getSheetId() !== this.state.properties.sheetId); this.state.properties.titles = titles; } } - UiUtil.confirmDelete方法大小写错误:
原代码中this.ui.ButtonSet.OK_CANCEL的ui应该是uI(和构造函数里的变量名一致):confirmDelete() { const response = this.uI.alert( "Confirm Deletion", "Delete this item?", this.uI.ButtonSet.OK_CANCEL ); // 其他逻辑保持不变 } - UiManager.confirmDelete函数未实例化UiUtil:
原代码中Ui未定义,需要先实例化UiUtil:function confirmDelete() { const uiUtil = new UiUtil(getSpreadsheetApp); const isConfirmed = uiUtil.confirmDelete(); if (isConfirmed) { removeToc(isConfirmed); } }
内容的提问来源于stack exchange,提问作者NeophyteLou
相关产品推荐
相关产品推荐

