Google Scripts / Basic JavaScript - 由调试器修复的问题

时间:2015-09-08 17:03:44

标签: javascript google-apps-script

我正在为Google表格添加Google Scripts,但是我尝试让脚本正常工作,然后才真正将其设置在工作表上。如果我在extractNumbers函数中的某处设置断点,下面的代码工作正常。如果我只是执行没有断点的代码,我会收到一个错误:

  

TypeError:无法调用方法"替换"未定义的。 (第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逻辑不仅有点不优雅,但对于我的目的,快速和肮脏是好的。我只是需要它来运行。

ALSO ,我读过其他新手JavaScript程序员,他们遇到与代码执行顺序相关的类似问题。如果有人希望链接到针对非高级受众的简明来源,那也会很棒。谢谢!

编辑:我把我的代码放到一个新的小提琴中它运行正常,但它在Google Scripts编辑器中继续失败,除非在带有断点的调试模式下运行。问题似乎是除非存在断点,否则函数参数不可用。任何人都可以访问可以尝试https://jsfiddle.net/hrzqg64L/的最新代码的Google脚本吗?

2 个答案:

答案 0 :(得分:2)

这些建议都没有找到你问题的根源 - 你的答案也没有,尽管你已经通过围绕所有问题避免了这个问题。

没有AJAX,没有异步行为 - 它比这更简单。 "参数阴影"同样是红鲱鱼。糟糕的编码习惯,是 - 但不是这里的一个因素。

  

如果有人希望链接到针对非高级受众的简明来源,那也会很棒。

抱歉 - 没有这样的事情。我可以解释一下发生了什么,但不能保证新手可以访问它。

例外

让我们澄清导致您发现的异常或抛出错误的原因。

如上所述,extractNumbers()如果传递给它的是null参数(或任何非字符串参数),则会抛出异常。如果您选择extractNumbers()然后按"运行",您将获得:

  

TypeError:无法调用方法"替换"未定义的。 (第36行,文件"")

这告诉你,在第36行,return str.replace( /\D+/g, '');,变量str包含一个undefined的对象(...并且没有replace()方法)。

对于防弹代码,您将检查您的参数以确保它们有效,并正确处理它们。有时候会使用有效的默认值,有时可能会返回错误或抛出一个更明确的参数问题的异常。

在Google调试程序中运行代码

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

  • phoneCheck()
  • extractNumbers()

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

这需要一些时间。为了在被要求执行特定功能时加快速度,如果全局符号是所请求函数或它可能调用的函数的依赖项,则 进行评估。还有另一个条件会触发全局符号的评估,也就是说,如果调试器可能需要停止并显示值。

发生这种情况时,将执行闭包之外的任何代码(例如 function 之外)。 这是您在设置断点时观察到的内容。

为什么设置断点时它会起作用?

如上所述,只要设置断点就会触发全局符号的评估。

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

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);
}

答案 1 :(得分:0)

终于找到了问题,但我并不完全理解它。

This question让我思考范围以及它在Google Script环境中的不同之处。我认为一个简单的解决方法是将整个脚本封装在自己的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;
  }
}

另外,我意识到这个脚本的功能与原始脚本不同,但我真的只是想解决这个问题。现在我有了,我可以正确完成脚本。

感谢大家的所有建议!我学到了很多好东西,尽管结果证明不是答案。