Javascript 如何包装对接受无限参数的Google Apps脚本函数的调用
一些Google应用程序脚本函数,如Logger.log()和Utility.formatString()接受无限参数 我想包装对Logger.log()或Utility.formatString()的调用,以便在最内部的函数调用中,我可以使用时间戳和我自己的文本作为结果字符串的前缀。通常您只需Javascript 如何包装对接受无限参数的Google Apps脚本函数的调用,javascript,google-apps-script,rhino,Javascript,Google Apps Script,Rhino,一些Google应用程序脚本函数,如Logger.log()和Utility.formatString()接受无限参数 我想包装对Logger.log()或Utility.formatString()的调用,以便在最内部的函数调用中,我可以使用时间戳和我自己的文本作为结果字符串的前缀。通常您只需。将当前模块的ags应用于函数,但在我的测试中,这并没有按预期工作。它导致错误TypeError:找不到对象的默认值。(第14行,文件“Code”)来自java/服务器端 这是我用于测试的代码。问题: 这
。将当前模块的ags应用于函数,但在我的测试中,这并没有按预期工作。它导致错误TypeError:找不到对象的默认值。(第14行,文件“Code”)
来自java/服务器端
这是我用于测试的代码。问题:
这是这些应用程序脚本方法中的错误吗
是否有一种变通方法或替代方法来实现我的目标
如果它是一个bug,我也会把它放在问题追踪器上
function testMyLogger() {
myLogger('Testing %s %s %s', 'one', 2, 'three');
}
function myLogger() {
// do common things like prefix a timestamp to the first arg
var logdate = Utilities.formatDate(new Date(), Session.getTimeZone(), "yyyy-MM-dd HH:mm:ss");
arguments[0]= logdate + " " + arguments[0];
Logger.log.apply(this, arguments);
// At the above line I get error "TypeError: Cannot find default value for object. (line 14, file "Code")"
// but I expected '<timestamp> Testing one 2.0 three' to the log (View > Logs...)
}
函数testMyLogger(){
myLogger('测试%s%s%s','1',2',3');
}
函数myLogger(){
//做一些常见的事情,比如在第一个参数前面加上时间戳
var logdate=Utilities.formatDate(new Date(),Session.getTimeZone(),“yyyy-MM-dd HH:MM:ss”);
参数[0]=logdate+“”+参数[0];
Logger.log.apply(这是参数);
//在上面的一行,我得到错误“TypeError:找不到对象的默认值。(第14行,文件“代码”)”
//但我希望日志中有“测试1 2.0 3”(查看>日志…)
}
尝试Logger.log.apply(Logger,参数)代码>很不幸,这不起作用,但是apply
和map
通常不能很好地与宿主对象上的函数配合使用(在浏览器中有时也是如此)。然而,这个可怕的丑陋的黑客将为你做的伎俩。将您的Logger.log.apply替换为:
for (var i = 0, arr = []; i < arguments.length; ++i)
arr.push('arguments[' + i + ']');
eval('Logger.log(' + arr.join() + ')');
更新:
或者我们可以,你知道,只是修复错误:)
我夸大了原始错误的严重性:call
和apply
今天在应用程序脚本主机对象上的95%的方法都能工作,但你碰巧碰到了一个目前不工作的方法。不幸的是,我无法向您解释该模式,因为我知道哪些模式可以在不引用内部代码的情况下工作。幸运的是,我的一位优秀同事诊断出了这个问题,并且已经解决了Logger.log.apply(Logger,…)
将在一两个版本中开始工作。请注意发行说明。向chris道歉,我已更正了该呼叫并更新了错误消息(我尝试了一系列变体,最初在此处记录了错误消息。感谢您尝试解决此问题,但这也会返回相同的错误“TypeError:找不到对象的默认值”.FYI:基础错误现在应该得到修复。这是正确的(工作)答案。不要这样做。执行Logger.log.apply(Logger..
。记住,要应用的第一个参数确定函数中的关键字this
指向什么。它几乎总是方法所属的对象,几乎从来都不是调用范围中的当前this
值。人们对其工作原理的误解是为什么认为调用和>apply
不能很好地处理本机对象-这不是真的,规范的解决方案目前在应用程序脚本中确实不起作用。作为工程团队的一员,我这么说:)但是,您可以自己轻松地验证它;我们不支持本机对象中的apply-on方法。此外,在其他地方也不支持它(例如,由于类似的原因,您不能在IE9中使用apply-on-console.log)。本机对象的实现有时比您预期的更混乱,并且ES规范中关于本机可调用项的规定在技术上允许实现者使用。我已经测试并接受了@CoreyG的解决方案。我使用了第一个,因为当我明年震惊地发现它时,它将是可读的。顺便说一句,Corey在供应商(Google)的该产品团队中,我确信黑客是必要的解决方法。它是否会/能够在AppsScript本机记录器对象上工作是实现者的问题。仅供参考:底层错误现在应该得到修复。使用调用
或应用
(干净的解决方案)似乎工作正常。
eval('Logger.log(' + [].slice.call(arguments, 0)
.map(function(x, y){ return 'arguments[' + y + ']'; }).join() + ')');