Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 试图弄清楚作用域是如何工作的_Javascript_Variables_Scope - Fatal编程技术网

Javascript 试图弄清楚作用域是如何工作的

Javascript 试图弄清楚作用域是如何工作的,javascript,variables,scope,Javascript,Variables,Scope,我试图在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 = v

我试图在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);

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

var foo = null;

function setFoo(val) {
  foo = val;
}

setFoo(10);

alert(foo);

试试看

您可以将范围视为一个术语,意思是您可以在代码中的特定“级别”上访问哪些变量。在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在函数外部,最好在函数上方。然后您可以使用
foo=val在
setFoo
中设置它
foo
则指您在上面的级别
setFoo
中声明的一个

foo
setFoo
alert
调用中都可以访问;将其与上面的示例代码进行比较(
function1
setFoo
a
foo
,而
警报
调用处于最顶层。
function2
b
c
在您的案例中不使用。)。

原始代码:

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

setFoo(10);

alert(foo); // Crash!
他们对修复坠机事件的建议是:

通过将foo声明移到函数外部来修复此问题

function setFoo(val) {
    foo = val;
}
我猜你对他们所说的“功能之外”的含义感到困惑

请尝试以下编辑的代码:

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"

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

function setFoo(val) {
    foo = val;
}

在JavaScript中,新的作用域仅由函数创建,当您在JavaScript中声明变量时,它仅对声明的同一函数中的代码可见,或对该函数内部的函数可见。由于foo最初是在SetFoo函数中声明的,因此SetFoo之外的任何东西都无法看到它,因此调用警报失败,因为gloabl范围中不存在foo

正如注释所示,将foo声明移出函数并移入全局范围(您可以将其视为包含所有内容的catch all函数)将允许您在调用alert时使用foo

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

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;}
})();
通过只将一个对象设置为全局对象,并通过该对象的方法提供interfae,可以更好地实现这一点。这样,就可以创建一个包含库中所有函数的命名空间。下一个示例使用对象文字来实现这一点。在javascript中,您可以通过将键/值对放在花括号之间来创建对象。键/值对是对象的属性。例如:

(function(){
    var privatevar = 10,otherprivate=20;

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

你到底不明白什么?您是否尝试将foo声明移到函数外部?请尝试以下链接: