将方法执行结果赋值给变量后,调用变量会重复执行方法吗?
变量赋值与方法重复执行的性能问题解答
核心结论:变量存储的是方法执行结果,不会重复触发原方法
当你将方法的执行结果赋值给变量时,变量保存的是方法运行后的最终值(或对象引用),后续调用变量时只会读取这个值,不会重新执行原方法。
一、GmailApp示例详解
假设你写了这样的代码:
const thisSubject = GmailApp.getInboxThreads()[x].getMessages()[y].getSubject(); // 多次使用thisSubject拼接字符串 const fullText = thisSubject + " - 标记1"; const anotherText = thisSubject + " - 标记2";
GmailApp.getInboxThreads()[x].getMessages()[y].getSubject()只会在赋值给thisSubject时执行一次,返回的主题字符串被存在变量中。- 后续每次调用
thisSubject,都是直接读取已存储的字符串,不会再触发Gmail API调用,也不会重复执行getSubject()或前面的线程、邮件获取操作。
二、JSON序列化的性能作用与适用场景
用JSON.parse(JSON.stringify(...))将对象转为纯数据副本,是否能提升性能?要分情况:
- 收益场景:如果需要多次读取Google服务返回对象(如
GmailThread、Sheet)的静态属性(比如主题、单元格值),序列化后的副本是本地纯数据,无需再和服务器交互,能减少API调用次数(这类远程调用是性能瓶颈)。 - 注意事项:
- 序列化会消耗额外CPU资源,只有当重复读取的次数足够多,抵消序列化成本时才划算。
- 序列化会丢失原对象的API方法(比如邮件的
markRead()、工作表的getRange()),如果后续需要操作对象,不能用这种方式。
对GmailApp.getInboxThreads()序列化是否合理?
- 若仅需读取线程的静态数据(主题、发送时间等):合理,能避免多次调用
getInboxThreads()(远程API调用成本高)。 - 若需要对线程执行操作(移动、删除、标记):不合理,因为序列化后的副本不是真正的
GmailThread对象,无法调用相关API。
三、SpreadsheetApp示例说明
场景1:存储工作表名称
const sheetName = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getName();
getActiveSpreadsheet()、getSheetByName()、getName()只会在赋值时执行一次,sheetName存储的是最终的字符串。- 后续使用
sheetName时,只是读取字符串,不会重复执行打开表格、获取工作表的操作。
场景2:存储工作表对象
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
sheet存储的是工作表对象的引用,后续调用sheet.getRange()等方法时,不会重复执行getActiveSpreadsheet()和getSheetByName(),但部分方法(如getRange().getValue())仍会触发与Google服务器的交互,这是服务对象的特性,和变量存储无关。
内容的提问来源于stack exchange,提问作者Anatoly Koshelev
相关产品推荐
相关产品推荐

