【问题标题】:google apps script loop variable to be declared var?谷歌应用程序脚本循环变量被声明为 var?
【发布时间】:2013-09-13 21:35:28
【问题描述】:

我想知道这是谷歌应用程序脚本(或整个 javascript)的一个功能还是一个错误。当我从循环内部调用一个函数时,我得到了一个奇怪的结果。现在,在被调用函数中有一个循环使用与调用循环上运行的变量相同的变量,这似乎会导致问题。代码如下:

 function dudi() {
   var folderName='FormsGenerator';
   var ss=new Array(2);
   for(o=0;o<2;o++){
     var str='dudo' + o;
     trashFile(str,folderName);
     ss[o]=SpreadsheetApp.create(str);
     Logger.log(str);
   }
  }
 function trashFile(fileName,folderName){
   var folder=DocsList.getFolder(folderName);
   var lFolder=folder.getFiles();
   for(o=0;o < lFolder.length;o++){
     if(lFolder[o].getName() == fileName) {
       DocsList.getFileById(lFolder[o].getId()).setTrashed(true);
     }
   }

发生的情况是调用函数中的循环在第一次迭代后停止。如果在垃圾文件中我将循环索引变量更改为“p”或者我使用“var o=0”而不是“o=0”,问题就会消失。我究竟做错了什么?这是众所周知的功能还是错误?我多年来一直使用 C 和 C++ 进行编程,但我对 javascript/GAS 还是很陌生。

最大

【问题讨论】:

    标签: javascript google-apps-script


    【解决方案1】:

    现在,在被调用函数中有一个循环使用与调用循环上运行的变量相同的变量,这似乎会导致问题。

    问题的原因是o 没有在任何一个函数中声明,所以你会成为The Horror of Implicit Globals 的牺牲品:在JavaScript 中,分配给一个不存在的变量会创建一个全局变量。 (见下文。)由于 o 最终成为全局变量,因此两个函数使用相同的 o,并相互干扰。

    只需在两个函数中声明o(例如:var o;),问题就会消失,因为每个函数都使用自己的局部变量而不是全局变量。

    这种隐含的全局变量是 JavaScript 原始设计的缺陷之一(所有语言都有设计缺陷)。他们在语言的新“严格”变体中解决了这个问题:如果启用严格模式,分配给不存在的变量会导致错误,而不是创建全局变量。

    示例:(假设在任何地方都没有声明 a。)

    松散模式:

    function foo() {
        a = "bar";    // <=== Creates a global variable called 'a'
    }
    

    严格模式:

    function foo() {
        "use strict";
    
        a = "bar";    // <=== Throws a ReferenceError
    }
    

    您可以将严格模式应用到所有代码,方法是将其包装为范围函数:

    (function() {
        "use strict";
    
        function foo() {
            a = "bar";    // <=== Throws a ReferenceError
        }
    })();
    

    您也可以将它应用到 script 标记中,方法是将其放在顶部:

    <script>
    "use strict";
    function foo() {
        a = "bar";    // <=== Throws a ReferenceError
    }
    </script>
    

    这既适用于上述内联脚本,也适用于通过src= 加载的 .js 文件。但请注意,如果您在 .js 文件的顶层执行此操作,则在组合脚本时必须小心! (这是我总是使用作用域函数的一个原因;另一个是我不想创建任何全局变量。)

    【讨论】:

    • 非常感谢赐教!我实际上是从 James Ferrera 的关于 Google Scripts 的书和 google 开发者页面中挑选示例。在那里我见过很多次循环,比如 for(i in someList){}。我想这也是错误的? i 是全局变量吗?
    • @Max:如果i 没有在任何地方声明,是的,这将使它成为一个隐式全局(在松散模式下)。不过,希望i 被声明在某个地方(也许在函数的顶部?)。你已经提到你有 C++ 经验,所以我会警告你 JavaScript(当前)没有块作用域,只有函数作用域、全局作用域和闭包。更多herehere(披露:两者都是我博客的链接)。
    • @TJCrowder,不幸的是,GAS 文档中有很多使用相同习语的示例
    • @Max:我既惊讶又不惊讶。也许链接一个?您确定他们没有在某处声明变量?
    猜你喜欢
    • 2015-10-25
    • 1970-01-01
    • 2022-11-16
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-28
    相关资源
    最近更新 更多