Google脚本/基本JavaScript-问题已由调试器修复

Google脚本/基本JavaScript-问题已由调试器修复,javascript,google-apps-script,Javascript,Google Apps Script,我正在为GoogleSheets开发一个GoogleScripts插件,但我正在尝试在我在工作表上实际设置它之前让脚本工作。如果我在extractNumbers函数的某个地方设置断点,下面的代码就可以正常工作。如果我只是在没有断点的情况下执行代码,我会得到一个错误: TypeError:无法调用未定义的方法“replace”。(第36行,文件“”) 代码如下: var myVar = phoneCheck("a1","a2","o1","o2"); Logger.log(myVar); fun

我正在为GoogleSheets开发一个GoogleScripts插件,但我正在尝试在我在工作表上实际设置它之前让脚本工作。如果我在extractNumbers函数的某个地方设置断点,下面的代码就可以正常工作。如果我只是在没有断点的情况下执行代码,我会得到一个错误:

TypeError:无法调用未定义的方法“replace”。(第36行,文件“”)

代码如下:

var myVar = phoneCheck("a1","a2","o1","o2");
Logger.log(myVar);

function phoneCheck(newCell,newHome,oldCell,oldHome) {
  Logger.clear();
  var newCell = extractNumbers(newCell);
  var oldCell = extractNumbers(oldCell);
  var newHome = extractNumbers(newHome);
  var oldHome = extractNumbers(oldHome);

  if (newCell === oldCell) {
    return newCell;
    exit;
  } else if (newCell === oldHome && newHome === oldCell) {
    return oldCell;
    exit;
  }

  if (newCell === '' && oldCell !== '' ) {
    return oldCell;
    exit;
  }

  if (newCell !== oldCell && newCell !== oldHome) {
   return newCell;
    exit;
  }

  return "No value found";
  exit;
}

function extractNumbers(input) {
  Logger.log(input);
  var str = input;
  return str.replace( /\D+/g, '');
}
现在我意识到我的if/then逻辑有点不雅观,但就我而言,快速和肮脏是好的。我只需要它运行

同样,我也读到过其他JavaScript新手在代码执行顺序方面也有类似的问题。如果有人想链接到一个针对非高级受众的简明来源,那也太好了。谢谢


编辑:我将我的代码放入一个新的提琴中,它工作正常,但在Google脚本编辑器中它仍然会失败,除非在带有断点的调试模式下运行。问题似乎是函数参数对函数不可用,除非有断点。任何人都可以使用谷歌脚本来尝试我的更新代码?

最终发现了这个问题,但我并不完全理解

让我想到了范围,以及它在Google脚本环境中的不同之处。我想一个简单的解决方法是将整个脚本封装在它自己的void函数中,它成功了!此外,我还使用数组对脚本进行了简化:

function init () {
  var numberArray = ["a3", "a2", "o3", "o10"];
  var myVar = phoneCheck(numberArray);
  Logger.log(myVar);

  function phoneCheck(myArray) {
    var phoneString = '';
    Logger.clear();
    var arrayLength = myArray.length;
    for (i = 0; i < arrayLength; i++) {
      phoneString += myArray[i].replace(/\D+/g, '');
    }
    return phoneString;
  }
}
函数初始化(){
var numberArray=[“a3”、“a2”、“o3”、“o10”];
var myVar=电话检查(numberArray);
Logger.log(myVar);
函数phoneCheck(myArray){
var phoneString='';
Logger.clear();
var arrayllength=myArray.length;
对于(i=0;i
另外,我意识到这个脚本的功能与原来的不同,但我只是想解决这个问题。现在我有了,我可以正确地完成脚本了


谢谢大家的建议!我学到了很多好东西,尽管它们不是问题的答案。

这些建议都没有找到问题的根源——你的答案也没有,尽管你通过在所有东西周围放置一个围栏来避免问题

没有AJAX,没有异步行为——比这更简单。“参数的阴影”同样是一个骗局。糟糕的编码实践,是的,但这不是一个因素

如果有人想链接到一个针对非高级受众的简明来源,那也太好了

对不起,没有这样的事。我可以解释发生了什么,但不能保证新手可以访问

例外 让我们澄清一下是什么导致了您观察到的异常或抛出的错误

如前所述,
extractNumbers()
如果向其传递了null参数(或任何非字符串参数),则将引发异常。如果您选择
extractNumbers()
,然后点击“运行”,您将得到:

TypeError:无法调用未定义的方法“replace”。(第36行,文件“”)

也就是说,在第36行,即
返回str.replace(/\D+/g')
,变量
str
包含一个
未定义的对象(…并且没有
replace()
方法)

对于防弹代码,您应该检查参数以确保它们有效,并适当地处理它们。有时,这将是一个有效的默认值,而其他时候,您可能会返回一个错误或抛出一个异常,该异常对于参数问题更为明确

在Google的调试器中运行代码 在Google的调试器中运行代码的唯一方法是选择一个函数,然后选择“运行”或“调试”。假设您发布了所有代码,您只有两个函数可供选择:

  • phoneCheck()
  • extractNumber()
每当GoogleApps脚本运行脚本的任何部分时,都会加载并扫描整个脚本以查找所有符号并检查语法。所有符号的范围以及函数和全局符号(任何闭包或代码块之外的符号)之间的任何依赖关系也会被注意到

这需要一些时间。为了在要求执行特定函数时加快速度,仅当全局符号是请求函数或它可能调用的函数的依赖项时,才会对其进行计算。还有另一种情况会触发对全局符号的求值,即调试器可能需要停止并显示值

发生这种情况时,将执行闭包外部(例如,函数外部)的任何代码这是设置断点时观察到的情况。

当设置断点时,它为什么工作? 如前所述,仅设置断点即可触发全局符号的计算

您可以使用不在任何闭包中的几行代码启动此脚本:

var myVar = phoneCheck("a1","a2","o1","o2");
Logger.log(myVar);
正是这段代码使用参数正确调用了
phoneCheck()
。由于计算了
myVar
phoneCheck()
将使用参数调用,然后使用定义的参数调用
extractNumbers()

不幸的是,由于调试器的工作方式,您不能选择自己运行该代码。你需要依赖这些副作用行为

如何解决这个问题? 简单。不要依赖全局代码来调用测试中的函数。相反,编写一个显式的测试函数,并调用它

function test_phoneCheck() {
  var myVar = phoneCheck("a1","a2","o1","o2");
  Logger.log(myVar);
}

通常,新手js程序员会因为不理解AJAX调用的异步性质而被绊倒。如果您发布的示例中有异步代码,我看不到。这可能与您如何使用var声明隐藏fn参数有关