【问题标题】:Trying to figure out how scope works试图弄清楚范围是如何工作的
【发布时间】:2011-12-14 12:28:23
【问题描述】:

我正在尝试在 codeacademy 上学习 JS,但我无法理解/通过这件事。有人可以提供答案并解释为什么会这样吗?将深深感激。

// This function tries to set foo to be the
// value specified.

function setFoo(val) {
  // foo is declared in a function. It is not
  // accessible outside of the function.
  var foo = val;
}

setFoo(10);

// Now that we are outside the function, foo is
// not defined and the program will crash! Fix this
// by moving the declaration of foo outside of the
// function. Make sure that setFoo will still update
// the value of foo.
alert(foo);

【问题讨论】:

标签: javascript variables scope


【解决方案1】:

您可以将范围视为一个术语,表示您可以在代码中的特定“级别”达到哪些变量。在 JavaScript 中,这些“级别”由函数定义。每个功能都引入了一个新级别。

以这个示例代码为例:

var a;
// you can access a at this level

function function1() {
  var b;
  // you can access a, b at this level

  function function2() {
    var c;
    // you can access a, b, c at this level
  }
}

所以在你的情况下,你应该在函数之外声明var foo;,最好在它上面。然后你可以将它设置在setFoofoo = val; 中。 foo 则指您在setFoo 以上级别声明的那个。

foosetFooalert 调用中都可以访问;与上面的示例代码比较(function1setFooafooalert 调用在最顶层。function2bc 不是在你的情况下使用。)。

【讨论】:

    【解决方案2】:
    // Create globale variable
    // (You should not use globale variables!)
    var foo;
    
    // set value
    function setFoo(val) {
      foo = val;
    }
    setFoo(10);
    
    // show value
    alert(foo);
    

    【讨论】:

      【解决方案3】:

      只需在任何函数之外声明foo,它将是全局的:

      var foo = null;
      
      function setFoo(val) {
        foo = val;
      }
      
      setFoo(10);
      
      alert(foo);
      

      试试吧!

      【讨论】:

        【解决方案4】:

        当你在 Javascript 中声明一个变量时,它只对与声明它的函数相同的代码或该函数内部的函数可见。因为 foo 最初是在 SetFoo 函数中声明的,SetFoo 之外的任何东西都无法看到它,所以对 alert 的调用失败,因为 foo 在全局范围内不存在。

        正如 cmets 所建议的,将 foo 的声明移出函数并进入全局范围(您可以将其视为包含所有内容的包罗万象的函数)将允许您在调用 alert 时使用 foo。

        var foo;
        function setFoo(val) {   
          foo = val; 
        }
        setFoo(10); 
        alert(foo); // No longer crashes
        

        【讨论】:

          【解决方案5】:

          Javascript 中的每个函数都有自己的作用域。这意味着您在此处使用 var 关键字定义的每个变量将仅在该函数中可用。这意味着当你调用setFoo(10) 时,你创建了变量 foo,给它一个值 5,之后它立即被销毁,因为它超出了范围。

          有多种方法可以解决这个问题。第一个是删除 var 关键字。这会将 foo 置于全局范围内,这意味着它在任何地方都可用。但是,这是不鼓励的,您希望保持全局范围尽可能整洁,这样如果您在同一页面上有多个人提供的 javascript 代码,他们就无法覆盖其他人的变量。另一种方法是:

          function setFoo(val){
              var foo = val;
              alertfoo = function(){
                  alert(foo)
              } 
          }
          

          在这个例子中,你在全局范围内的唯一东西是 alertfoo 函数,因为你希望它在任何地方都可用。 alertfoo 函数在 setFoo 函数内部定义,这意味着尽管在 setfoo 执行后 foo 应该已经超出范围,但它仍保存在内存中,因为 alertfoo 可以访问它。

          这带来了一些不错的技巧。例如,假设您正在创建一个将包含在其他人页面上的 javascript 库,您将希望创建一个范围,您可以在其中定义变量,而不会污染全局范围。最常见的方法是声明一个自执行函数。这是一个定义后立即执行的函数,如下所示:

          (function(){
              //set variables you want to be global in your own code
              var mainpage = document.getElementById('main');
          
             //define functions you want to make available to other people in a way that puts them in the global scope
             setMainElement = function(newmain){mainpage = newmain;}
          })();
          

          您可以通过仅将一个对象设为全局对象,并通过该对象的方法提供您的接口来使这一点变得更好,这样,您就可以创建一个包含库包含的所有函数的命名空间。下一个示例使用对象文字来执行此操作。在 javascript 中,您可以通过在花括号之间放置键/值对来创建对象。键/值对是对象的属性。例如:

          (function(){
              var privatevar = 10,otherprivate=20;
          
               publicInterface = {
                  'addToPrivate': function(x){privatevar+=x;},
                  'getPrivate': function(){return private}
               };
          })();
          

          【讨论】:

            【解决方案6】:

            原码:

            function setFoo(val) {
              var foo = val;
            }
            
            setFoo(10);
            
            alert(foo); // Crash!
            

            他们修复崩溃的建议:

            通过将 foo 的声明移到函数之外来解决此问题

            我猜你对“函数之外”的含义感到困惑。

            试试这个编辑过的代码:

            var foo = 5; // "var" declares the variable to be in this outer scope
            
            function setFoo(val) {
              foo = val; // but we can still access it in this inner scope...
            }
            
            setFoo(10);
            
            alert(foo); // Displays a dialog box that says "10"
            

            【讨论】:

              【解决方案7】:

              函数中定义的变量只在函数中有效

              function setFoo(val) {
                  foo = val;
              }
              

              【讨论】:

                【解决方案8】:

                在 JavaScript 中,新作用域只能由函数创建

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-04-01
                  • 2012-03-28
                  • 1970-01-01
                  • 1970-01-01
                  • 2023-03-15
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多