【问题标题】:why javascript can understand the variable out of function and loop?为什么javascript可以理解函数和循环之外的变量?
【发布时间】:2017-10-14 08:06:51
【问题描述】:

我不认为我的问题与 How do I return the response from an asynchronous call? 重复

我看到,在其他语言(C#)中,声明了一个变量 在函数或循环中,当您退出函数或循环时,他们无法访问已在其他函数中声明的变量,但在 javascript 中可以。

 $(document).ready(function () {
        Text();
        Tex2();
    });
    function Text() {
        for (xxi = 0; xxi < 10; xxi++) {
            console.log(xxi);
            iix = 99;
        }
        console.log(xxi + iix);
        Tex2();
    }
    function Tex2() {
        console.log("What the hel:" + (xxi + iix));
    }

结果是:

有没有人可以为我详细解释一下?谢谢。

【问题讨论】:

  • iix = 99; 没有声明......就好像你有window.iix = 99......并且任何对iix的引用就像window.iix......所以,它有效 - 学习更多,搜索 javascript 范围链 - 此外,Tex2 在 Tex1 的末尾被调用一次,然后在 document.ready 中再次调用
  • stackoverflow.com/questions/500431/… 很好地概括了 JavaScript 的作用域。
  • 答案没有提到的一件事,@DocMax 就是为什么 iix 在这种情况下是全局的
  • 如果你声明一个没有关键字的变量,它就变成了一个全局变量。 a=1 是全局的,但 var a = 1let a = 1 不是。虽然,javascript 也使用范围链,但这不是这里的问题。
  • @Araymer - 范围链接可能与 iixxxi 对 Tex2 的“可见性”有关:p(我刚刚意识到 iix 和 xxi 都是全局的:p)

标签: javascript jquery


【解决方案1】:

您将它们声明为全局变量而不使用var 关键字。使用var 关键字将它们限定在预期的范围内,或者在javascript 文件的顶部使用"use strict"。您还可以使用 let 关键字将它们限定在它们的本地范围内。

  1. 未使用var and let keywords 声明的变量具有全局范围。

  2. 使用 var 关键字声明的变量被 javascript 视为其封闭范围或函数内的第一条语句。因此,它在全局范围内定义了一个变量,或者在整个函数的本地定义了一个变量,而不管块范围如何。

  3. let 关键字允许声明变量的范围仅限于使用它的块、语句或表达式。

我在下面创建了 3 个 sn-ps。一种带有let 关键字,一种带有var 关键字,另一种带有use strict 关键字。运行以查看相同代码段的变化行为。

以下片段

let关键字sn-p。运行以查看该变量在块范围之外甚至不可用。

//let keyword snippet. See variable is not available outside block scope even.

$(document).ready(function () {
        Text();
        Tex2();
    });
    function Text() {
        for (let xxi = 0; xxi < 10; xxi++) {
            console.log(xxi);
           let iix = 99;
        }
        var xyz; 
        try
        {
          xyz = xxi + iix;
        } 
        catch (e){
          xyz = e;
        }
        console.log(xyz);
        Tex2();
    }
    function Tex2() {
    var abc;
     try
     {
      abc = (xxi + iix);
     } 
     catch (e){
        abc = e;
      }
        console.log("What the hel:" + abc);
    }
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"&gt;&lt;/script&gt;
var 关键字 sn-p。运行以查看该变量在函数范围之外不可用。
//var keyword snippet. See variable is not available outside function scope.

$(document).ready(function () {
        Text();
        Tex2();
    });
    function Text() {
        for (var xxi = 0; xxi < 10; xxi++) {
            console.log(xxi);
           var iix = 99;
        }
        var xyz; 
        try
        {
          xyz = xxi + iix;
        } 
        catch (e){
          xyz = e;
        }
        console.log(xyz);
        Tex2();
    }
    function Tex2() {
    var abc;
     try
     {
      abc = (xxi + iix);
     } 
     catch (e){
        abc = e;
      }
        console.log("What the hel:" + abc);
    }
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"&gt;&lt;/script&gt;

use strict关键字sn-p。运行看看它根本不会运行。这是您使用严格的代码。

//Your snippet with "use strict". Will not work at all.
"use strict"

$(document).ready(function () {
        Text();
        Tex2();
    });
    function Text() {
        for (xxi = 0; xxi < 10; xxi++) {
            console.log(xxi);
            iix = 99;
        }
        console.log(xxi + iix);
        Tex2();
    }
    function Tex2() {
        console.log("What the hel:" + (xxi + iix));
    }
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"&gt;&lt;/script&gt;

【讨论】:

    【解决方案2】:

    你需要声明变量,否则作用域会和window.iix一样。下面的 sn-p 具有您期望的结果(错误)。

    我已将行 for (xxi = 0; xxi &lt; 10; xxi++) { 更改为 for (var xxi = 0; xxi &lt; 10; xxi++) {

     $(document).ready(function () {
            Text();
            Tex2();
        });
        function Text() {
         
            for (var xxi = 0; xxi < 10; xxi++) {
                console.log(xxi);
                iix = 99;
            }
            console.log(xxi + iix);
            Tex2();
        }
        function Tex2() {
            console.log("What the hel:" + (xxi + iix));
        }
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"&gt;&lt;/script&gt;

    【讨论】:

    • 谢谢,我已经测试过了,但是没有出现错误。它有错误的功能。能详细点吗
    【解决方案3】:

    当你不使用var 来声明一个变量时,它被理解为一个全局变量。
    如果你每次都使用varlet,你的代码中发生的事情就不会再发生了声明一个变量。

    【讨论】:

    • 谢谢,我已经测试过了,但是没有出现错误。我一直在 for 循环中测试 var xxi。能详细点吗?
    • 尝试刷新您的控制台或在另一个窗口的控制台上运行您的代码。你的两个变量应该用 var 关键字声明。之后如果你运行它会抛出异常
    【解决方案4】:

    任何未在函数内部声明的变量,都被视为窗口变量:

        for (xxi = 0; xxi < 10; xxi++) {
            console.log(xxi); // this variable
            iix = 99; // this variable
        }
    

    如果你这样做了,javascript 将不会读取范围之外的变量:

        for (var xxi = 0; xxi < 10; xxi++) {
            console.log(xxi);
            var iix = 99;
        }
    

    解释(让我们理解使用声明而不是寻找错误):

        var xxi = "one"; //global variable
        var iix = "two"; //global variable
        globalVar = "three"; // window variable i.e. window.globalVar
        var getValues = function () {
             var xxi; //local variable for the scope 
             var iix; //local variable for the scope 
             for (xxi = 0; xxi < 10; xxi++) {
                console.log(xxi); // takes the local variable
                iix = 99; //local change of value
             }
             globalVar = 100; //change of value to window variable accessible inside
        };
        getValues();
        var seeValues = function () {
            console.log(xxi); //"one" //Displays the value of global because the local variable of getValues() is not accessible outside
            console.log(iix); //"two" //Same as above
            console.log(globalVar); //100 and not "three" //Displays the altered window variable
        };
        seeValues();
    

    查看此链接了解详细信息:http://www.dotnettricks.com/learn/javascript/understanding-local-and-global-variables-in-javascriptWhat's the difference between a global var and a window.variable in javascript?

    【讨论】:

    • 谢谢,我已经测试过了,但是没有出现错误。我一直在 for 循环中测试 var xxi。能详细解释一下吗?
    • 查看编辑中的详细说明。如果您觉得有帮助,请勾选答案:)
    猜你喜欢
    • 2018-09-21
    • 2016-02-12
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多